File: /usr/src/linux/arch/mips/mm/andes.c

1     /*
2      * andes.c: MMU and cache operations for the R10000 (ANDES).
3      *
4      * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
5      */
6     #include <linux/init.h>
7     #include <linux/kernel.h>
8     #include <linux/sched.h>
9     #include <linux/mm.h>
10     #include <asm/page.h>
11     #include <asm/pgtable.h>
12     #include <asm/system.h>
13     #include <asm/sgialib.h>
14     #include <asm/mmu_context.h>
15     
16     /* page functions */
17     void andes_clear_page(void * page)
18     {
19     	__asm__ __volatile__(
20     		".set\tnoreorder\n\t"
21     		".set\tnoat\n\t"
22     		"addiu\t$1,%0,%2\n"
23     		"1:\tsw\t$0,(%0)\n\t"
24     		"sw\t$0,4(%0)\n\t"
25     		"sw\t$0,8(%0)\n\t"
26     		"sw\t$0,12(%0)\n\t"
27     		"addiu\t%0,32\n\t"
28     		"sw\t$0,-16(%0)\n\t"
29     		"sw\t$0,-12(%0)\n\t"
30     		"sw\t$0,-8(%0)\n\t"
31     		"bne\t$1,%0,1b\n\t"
32     		"sw\t$0,-4(%0)\n\t"
33     		".set\tat\n\t"
34     		".set\treorder"
35     		:"=r" (page)
36     		:"0" (page),
37     		 "I" (PAGE_SIZE)
38     		:"$1","memory");
39     }
40     
41     static void andes_copy_page(void * to, void * from)
42     {
43     	unsigned long dummy1, dummy2;
44     	unsigned long reg1, reg2, reg3, reg4;
45     
46     	__asm__ __volatile__(
47     		".set\tnoreorder\n\t"
48     		".set\tnoat\n\t"
49     		"addiu\t$1,%0,%8\n"
50     		"1:\tlw\t%2,(%1)\n\t"
51     		"lw\t%3,4(%1)\n\t"
52     		"lw\t%4,8(%1)\n\t"
53     		"lw\t%5,12(%1)\n\t"
54     		"sw\t%2,(%0)\n\t"
55     		"sw\t%3,4(%0)\n\t"
56     		"sw\t%4,8(%0)\n\t"
57     		"sw\t%5,12(%0)\n\t"
58     		"lw\t%2,16(%1)\n\t"
59     		"lw\t%3,20(%1)\n\t"
60     		"lw\t%4,24(%1)\n\t"
61     		"lw\t%5,28(%1)\n\t"
62     		"sw\t%2,16(%0)\n\t"
63     		"sw\t%3,20(%0)\n\t"
64     		"sw\t%4,24(%0)\n\t"
65     		"sw\t%5,28(%0)\n\t"
66     		"addiu\t%0,64\n\t"
67     		"addiu\t%1,64\n\t"
68     		"lw\t%2,-32(%1)\n\t"
69     		"lw\t%3,-28(%1)\n\t"
70     		"lw\t%4,-24(%1)\n\t"
71     		"lw\t%5,-20(%1)\n\t"
72     		"sw\t%2,-32(%0)\n\t"
73     		"sw\t%3,-28(%0)\n\t"
74     		"sw\t%4,-24(%0)\n\t"
75     		"sw\t%5,-20(%0)\n\t"
76     		"lw\t%2,-16(%1)\n\t"
77     		"lw\t%3,-12(%1)\n\t"
78     		"lw\t%4,-8(%1)\n\t"
79     		"lw\t%5,-4(%1)\n\t"
80     		"sw\t%2,-16(%0)\n\t"
81     		"sw\t%3,-12(%0)\n\t"
82     		"sw\t%4,-8(%0)\n\t"
83     		"bne\t$1,%0,1b\n\t"
84     		"sw\t%5,-4(%0)\n\t"
85     		".set\tat\n\t"
86     		".set\treorder"
87     		:"=r" (dummy1), "=r" (dummy2),
88     		 "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
89     		:"0" (to), "1" (from),
90     		 "I" (PAGE_SIZE));
91     }
92     
93     /* Cache operations. XXX Write these dave... */
94     static inline void andes_flush_cache_all(void)
95     {
96     	/* XXX */
97     }
98     
99     static void andes_flush_cache_mm(struct mm_struct *mm)
100     {
101     	/* XXX */
102     }
103     
104     static void andes_flush_cache_range(struct mm_struct *mm,
105     				    unsigned long start,
106     				    unsigned long end)
107     {
108     	/* XXX */
109     }
110     
111     static void andes_flush_cache_page(struct vm_area_struct *vma,
112     				   unsigned long page)
113     {
114     	/* XXX */
115     }
116     
117     static void andes_flush_page_to_ram(struct page * page)
118     {
119     	/* XXX */
120     }
121     
122     static void __andes_flush_icache_range(unsigned long start, unsigned long end)
123     {
124     	/* XXX */
125     }
126     
127     static void andes_flush_icache_page(struct vm_area_struct *vma,
128                                         struct page *page)
129     {
130     	/* XXX */
131     }
132     
133     static void andes_flush_cache_sigtramp(unsigned long page)
134     {
135     	protected_writeback_dcache_line(addr & ~(dc_lsize - 1));
136     	protected_flush_icache_line(addr & ~(ic_lsize - 1));
137     }
138     
139     /* TLB operations. XXX Write these dave... */
140     void flush_tlb_all(void)
141     {
142     	/* XXX */
143     }
144     
145     void flush_tlb_mm(struct mm_struct *mm)
146     {
147     	/* XXX */
148     }
149     
150     void flush_tlb_range(struct mm_struct *mm, unsigned long start,
151     				  unsigned long end)
152     {
153     	/* XXX */
154     }
155     
156     void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
157     {
158     	/* XXX */
159     }
160     
161     void pgd_init(unsigned long page)
162     {
163     }
164     
165     void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
166     				  unsigned long entryhi, unsigned long pagemask)
167     {
168             /* XXX */
169     }
170     
171     void __init ld_mmu_andes(void)
172     {
173     	_clear_page = andes_clear_page;
174     	_copy_page = andes_copy_page;
175     
176     	_flush_cache_all = andes_flush_cache_all;
177     	___flush_cache_all = andes_flush_cache_all;
178     	_flush_cache_mm = andes_flush_cache_mm;
179     	_flush_cache_range = andes_flush_cache_range;
180     	_flush_cache_page = andes_flush_cache_page;
181     	_flush_cache_sigtramp = andes_flush_cache_sigtramp;
182     	_flush_page_to_ram = andes_flush_page_to_ram;
183     	_flush_icache_page = andes_flush_icache_page;
184     	_flush_icache_range = andes_flush_icache_range;
185     
186     	write_32bit_cp0_register(CP0_FRAMEMASK, 0);
187     
188     	flush_cache_all();
189     	flush_tlb_all();
190     
191     	/*
192     	 * The R10k might even work for Linux/MIPS - but we're paranoid
193     	 * and refuse to run until this is tested on real silicon
194     	 */
195     	panic("CPU too expensive - making holiday in the ANDES!");
196     }
197