diff options
author | David S. Miller <davem@sunset.davemloft.net> | 2006-02-12 00:57:54 -0500 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-03-20 04:12:25 -0500 |
commit | c4bce90ea2069e5a87beac806de3090ab32128d5 (patch) | |
tree | 3983a206c8060ef65ba17945d1c9f69e68d88b3d /arch/sparc64/kernel/setup.c | |
parent | 490384e752a43aa281ed533e9de2da36df25c337 (diff) |
[SPARC64]: Deal with PTE layout differences in SUN4V.
Yes, you heard it right, they changed the PTE layout for
SUN4V. Ho hum...
This is the simple and inefficient way to support this.
It'll get optimized, don't worry.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/setup.c')
-rw-r--r-- | arch/sparc64/kernel/setup.c | 274 |
1 files changed, 0 insertions, 274 deletions
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c index f36b257b2e44..ca75f3b26a37 100644 --- a/arch/sparc64/kernel/setup.c +++ b/arch/sparc64/kernel/setup.c | |||
@@ -64,12 +64,6 @@ struct screen_info screen_info = { | |||
64 | 16 /* orig-video-points */ | 64 | 16 /* orig-video-points */ |
65 | }; | 65 | }; |
66 | 66 | ||
67 | /* Typing sync at the prom prompt calls the function pointed to by | ||
68 | * the sync callback which I set to the following function. | ||
69 | * This should sync all filesystems and return, for now it just | ||
70 | * prints out pretty messages and returns. | ||
71 | */ | ||
72 | |||
73 | void (*prom_palette)(int); | 67 | void (*prom_palette)(int); |
74 | void (*prom_keyboard)(void); | 68 | void (*prom_keyboard)(void); |
75 | 69 | ||
@@ -79,263 +73,6 @@ prom_console_write(struct console *con, const char *s, unsigned n) | |||
79 | prom_write(s, n); | 73 | prom_write(s, n); |
80 | } | 74 | } |
81 | 75 | ||
82 | static struct console prom_console = { | ||
83 | .name = "prom", | ||
84 | .write = prom_console_write, | ||
85 | .flags = CON_CONSDEV | CON_ENABLED, | ||
86 | .index = -1, | ||
87 | }; | ||
88 | |||
89 | #define PROM_TRUE -1 | ||
90 | #define PROM_FALSE 0 | ||
91 | |||
92 | /* Pretty sick eh? */ | ||
93 | int prom_callback(long *args) | ||
94 | { | ||
95 | struct console *cons, *saved_console = NULL; | ||
96 | unsigned long flags; | ||
97 | char *cmd; | ||
98 | extern spinlock_t prom_entry_lock; | ||
99 | |||
100 | if (!args) | ||
101 | return -1; | ||
102 | if (!(cmd = (char *)args[0])) | ||
103 | return -1; | ||
104 | |||
105 | /* | ||
106 | * The callback can be invoked on the cpu that first dropped | ||
107 | * into prom_cmdline after taking the serial interrupt, or on | ||
108 | * a slave processor that was smp_captured() if the | ||
109 | * administrator has done a switch-cpu inside obp. In either | ||
110 | * case, the cpu is marked as in-interrupt. Drop IRQ locks. | ||
111 | */ | ||
112 | irq_exit(); | ||
113 | |||
114 | /* XXX Revisit the locking here someday. This is a debugging | ||
115 | * XXX feature so it isnt all that critical. -DaveM | ||
116 | */ | ||
117 | local_irq_save(flags); | ||
118 | |||
119 | spin_unlock(&prom_entry_lock); | ||
120 | cons = console_drivers; | ||
121 | while (cons) { | ||
122 | unregister_console(cons); | ||
123 | cons->flags &= ~(CON_PRINTBUFFER); | ||
124 | cons->next = saved_console; | ||
125 | saved_console = cons; | ||
126 | cons = console_drivers; | ||
127 | } | ||
128 | register_console(&prom_console); | ||
129 | if (!strcmp(cmd, "sync")) { | ||
130 | prom_printf("PROM `%s' command...\n", cmd); | ||
131 | show_free_areas(); | ||
132 | if (current->pid != 0) { | ||
133 | local_irq_enable(); | ||
134 | sys_sync(); | ||
135 | local_irq_disable(); | ||
136 | } | ||
137 | args[2] = 0; | ||
138 | args[args[1] + 3] = -1; | ||
139 | prom_printf("Returning to PROM\n"); | ||
140 | } else if (!strcmp(cmd, "va>tte-data")) { | ||
141 | unsigned long ctx, va; | ||
142 | unsigned long tte = 0; | ||
143 | long res = PROM_FALSE; | ||
144 | |||
145 | ctx = args[3]; | ||
146 | va = args[4]; | ||
147 | if (ctx) { | ||
148 | /* | ||
149 | * Find process owning ctx, lookup mapping. | ||
150 | */ | ||
151 | struct task_struct *p; | ||
152 | struct mm_struct *mm = NULL; | ||
153 | pgd_t *pgdp; | ||
154 | pud_t *pudp; | ||
155 | pmd_t *pmdp; | ||
156 | pte_t *ptep; | ||
157 | pte_t pte; | ||
158 | |||
159 | for_each_process(p) { | ||
160 | mm = p->mm; | ||
161 | if (CTX_NRBITS(mm->context) == ctx) | ||
162 | break; | ||
163 | } | ||
164 | if (!mm || | ||
165 | CTX_NRBITS(mm->context) != ctx) | ||
166 | goto done; | ||
167 | |||
168 | pgdp = pgd_offset(mm, va); | ||
169 | if (pgd_none(*pgdp)) | ||
170 | goto done; | ||
171 | pudp = pud_offset(pgdp, va); | ||
172 | if (pud_none(*pudp)) | ||
173 | goto done; | ||
174 | pmdp = pmd_offset(pudp, va); | ||
175 | if (pmd_none(*pmdp)) | ||
176 | goto done; | ||
177 | |||
178 | /* Preemption implicitly disabled by virtue of | ||
179 | * being called from inside OBP. | ||
180 | */ | ||
181 | ptep = pte_offset_map(pmdp, va); | ||
182 | pte = *ptep; | ||
183 | if (pte_present(pte)) { | ||
184 | tte = pte_val(pte); | ||
185 | res = PROM_TRUE; | ||
186 | } | ||
187 | pte_unmap(ptep); | ||
188 | goto done; | ||
189 | } | ||
190 | |||
191 | if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) { | ||
192 | if (tlb_type == spitfire) { | ||
193 | extern unsigned long sparc64_kern_pri_context; | ||
194 | |||
195 | /* Spitfire Errata #32 workaround */ | ||
196 | __asm__ __volatile__( | ||
197 | "stxa %0, [%1] %2\n\t" | ||
198 | "flush %%g6" | ||
199 | : /* No outputs */ | ||
200 | : "r" (sparc64_kern_pri_context), | ||
201 | "r" (PRIMARY_CONTEXT), | ||
202 | "i" (ASI_DMMU)); | ||
203 | } | ||
204 | |||
205 | /* | ||
206 | * Locked down tlb entry. | ||
207 | */ | ||
208 | |||
209 | if (tlb_type == spitfire) { | ||
210 | tte = spitfire_get_dtlb_data(SPITFIRE_HIGHEST_LOCKED_TLBENT); | ||
211 | res = PROM_TRUE; | ||
212 | } else if (tlb_type == cheetah || tlb_type == cheetah_plus) { | ||
213 | tte = cheetah_get_ldtlb_data(CHEETAH_HIGHEST_LOCKED_TLBENT); | ||
214 | res = PROM_TRUE; | ||
215 | } | ||
216 | goto done; | ||
217 | } | ||
218 | |||
219 | if (va < PGDIR_SIZE) { | ||
220 | /* | ||
221 | * vmalloc or prom_inherited mapping. | ||
222 | */ | ||
223 | pgd_t *pgdp; | ||
224 | pud_t *pudp; | ||
225 | pmd_t *pmdp; | ||
226 | pte_t *ptep; | ||
227 | pte_t pte; | ||
228 | int error; | ||
229 | |||
230 | if ((va >= LOW_OBP_ADDRESS) && (va < HI_OBP_ADDRESS)) { | ||
231 | tte = prom_virt_to_phys(va, &error); | ||
232 | if (!error) | ||
233 | res = PROM_TRUE; | ||
234 | goto done; | ||
235 | } | ||
236 | pgdp = pgd_offset_k(va); | ||
237 | if (pgd_none(*pgdp)) | ||
238 | goto done; | ||
239 | pudp = pud_offset(pgdp, va); | ||
240 | if (pud_none(*pudp)) | ||
241 | goto done; | ||
242 | pmdp = pmd_offset(pudp, va); | ||
243 | if (pmd_none(*pmdp)) | ||
244 | goto done; | ||
245 | |||
246 | /* Preemption implicitly disabled by virtue of | ||
247 | * being called from inside OBP. | ||
248 | */ | ||
249 | ptep = pte_offset_kernel(pmdp, va); | ||
250 | pte = *ptep; | ||
251 | if (pte_present(pte)) { | ||
252 | tte = pte_val(pte); | ||
253 | res = PROM_TRUE; | ||
254 | } | ||
255 | goto done; | ||
256 | } | ||
257 | |||
258 | if (va < PAGE_OFFSET) { | ||
259 | /* | ||
260 | * No mappings here. | ||
261 | */ | ||
262 | goto done; | ||
263 | } | ||
264 | |||
265 | if (va & (1UL << 40)) { | ||
266 | /* | ||
267 | * I/O page. | ||
268 | */ | ||
269 | |||
270 | tte = (__pa(va) & _PAGE_PADDR) | | ||
271 | _PAGE_VALID | _PAGE_SZ4MB | | ||
272 | _PAGE_E | _PAGE_P | _PAGE_W; | ||
273 | res = PROM_TRUE; | ||
274 | goto done; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Normal page. | ||
279 | */ | ||
280 | tte = (__pa(va) & _PAGE_PADDR) | | ||
281 | _PAGE_VALID | _PAGE_SZ4MB | | ||
282 | _PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W; | ||
283 | res = PROM_TRUE; | ||
284 | |||
285 | done: | ||
286 | if (res == PROM_TRUE) { | ||
287 | args[2] = 3; | ||
288 | args[args[1] + 3] = 0; | ||
289 | args[args[1] + 4] = res; | ||
290 | args[args[1] + 5] = tte; | ||
291 | } else { | ||
292 | args[2] = 2; | ||
293 | args[args[1] + 3] = 0; | ||
294 | args[args[1] + 4] = res; | ||
295 | } | ||
296 | } else if (!strcmp(cmd, ".soft1")) { | ||
297 | unsigned long tte; | ||
298 | |||
299 | tte = args[3]; | ||
300 | prom_printf("%lx:\"%s%s%s%s%s\" ", | ||
301 | (tte & _PAGE_SOFT) >> 7, | ||
302 | tte & _PAGE_MODIFIED ? "M" : "-", | ||
303 | tte & _PAGE_ACCESSED ? "A" : "-", | ||
304 | tte & _PAGE_READ ? "W" : "-", | ||
305 | tte & _PAGE_WRITE ? "R" : "-", | ||
306 | tte & _PAGE_PRESENT ? "P" : "-"); | ||
307 | |||
308 | args[2] = 2; | ||
309 | args[args[1] + 3] = 0; | ||
310 | args[args[1] + 4] = PROM_TRUE; | ||
311 | } else if (!strcmp(cmd, ".soft2")) { | ||
312 | unsigned long tte; | ||
313 | |||
314 | tte = args[3]; | ||
315 | prom_printf("%lx ", (tte & 0x07FC000000000000UL) >> 50); | ||
316 | |||
317 | args[2] = 2; | ||
318 | args[args[1] + 3] = 0; | ||
319 | args[args[1] + 4] = PROM_TRUE; | ||
320 | } else { | ||
321 | prom_printf("unknown PROM `%s' command...\n", cmd); | ||
322 | } | ||
323 | unregister_console(&prom_console); | ||
324 | while (saved_console) { | ||
325 | cons = saved_console; | ||
326 | saved_console = cons->next; | ||
327 | register_console(cons); | ||
328 | } | ||
329 | spin_lock(&prom_entry_lock); | ||
330 | local_irq_restore(flags); | ||
331 | |||
332 | /* | ||
333 | * Restore in-interrupt status for a resume from obp. | ||
334 | */ | ||
335 | irq_enter(); | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | unsigned int boot_flags = 0; | 76 | unsigned int boot_flags = 0; |
340 | #define BOOTME_DEBUG 0x1 | 77 | #define BOOTME_DEBUG 0x1 |
341 | #define BOOTME_SINGLE 0x2 | 78 | #define BOOTME_SINGLE 0x2 |
@@ -483,17 +220,6 @@ char reboot_command[COMMAND_LINE_SIZE]; | |||
483 | 220 | ||
484 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; | 221 | static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; |
485 | 222 | ||
486 | void register_prom_callbacks(void) | ||
487 | { | ||
488 | prom_setcallback(prom_callback); | ||
489 | prom_feval(": linux-va>tte-data 2 \" va>tte-data\" $callback drop ; " | ||
490 | "' linux-va>tte-data to va>tte-data"); | ||
491 | prom_feval(": linux-.soft1 1 \" .soft1\" $callback 2drop ; " | ||
492 | "' linux-.soft1 to .soft1"); | ||
493 | prom_feval(": linux-.soft2 1 \" .soft2\" $callback 2drop ; " | ||
494 | "' linux-.soft2 to .soft2"); | ||
495 | } | ||
496 | |||
497 | static void __init per_cpu_patch(void) | 223 | static void __init per_cpu_patch(void) |
498 | { | 224 | { |
499 | #ifdef CONFIG_SMP | 225 | #ifdef CONFIG_SMP |