aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/setup.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-12 00:57:54 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:12:25 -0500
commitc4bce90ea2069e5a87beac806de3090ab32128d5 (patch)
tree3983a206c8060ef65ba17945d1c9f69e68d88b3d /arch/sparc64/kernel/setup.c
parent490384e752a43aa281ed533e9de2da36df25c337 (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.c274
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
73void (*prom_palette)(int); 67void (*prom_palette)(int);
74void (*prom_keyboard)(void); 68void (*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
82static 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? */
93int 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
339unsigned int boot_flags = 0; 76unsigned 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
484static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 }; 221static struct pt_regs fake_swapper_regs = { { 0, }, 0, 0, 0, 0 };
485 222
486void 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
497static void __init per_cpu_patch(void) 223static void __init per_cpu_patch(void)
498{ 224{
499#ifdef CONFIG_SMP 225#ifdef CONFIG_SMP