aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r--arch/sparc64/kernel/itlb_miss.S4
-rw-r--r--arch/sparc64/kernel/ktlb.S12
-rw-r--r--arch/sparc64/kernel/setup.c274
-rw-r--r--arch/sparc64/kernel/sun4v_tlb_miss.S3
-rw-r--r--arch/sparc64/kernel/tsb.S9
5 files changed, 11 insertions, 291 deletions
diff --git a/arch/sparc64/kernel/itlb_miss.S b/arch/sparc64/kernel/itlb_miss.S
index 97facce27aa..730caa4a150 100644
--- a/arch/sparc64/kernel/itlb_miss.S
+++ b/arch/sparc64/kernel/itlb_miss.S
@@ -6,9 +6,10 @@
6 nop ! Delay slot (fill me) 6 nop ! Delay slot (fill me)
7 TSB_LOAD_QUAD(%g1, %g4) ! Load TSB entry 7 TSB_LOAD_QUAD(%g1, %g4) ! Load TSB entry
8 cmp %g4, %g6 ! Compare TAG 8 cmp %g4, %g6 ! Compare TAG
9 sethi %hi(_PAGE_EXEC), %g4 ! Setup exec check 9 sethi %hi(PAGE_EXEC), %g4 ! Setup exec check
10 10
11/* ITLB ** ICACHE line 2: TSB compare and TLB load */ 11/* ITLB ** ICACHE line 2: TSB compare and TLB load */
12 ldx [%g4 + %lo(PAGE_EXEC)], %g4
12 bne,pn %xcc, tsb_miss_itlb ! Miss 13 bne,pn %xcc, tsb_miss_itlb ! Miss
13 mov FAULT_CODE_ITLB, %g3 14 mov FAULT_CODE_ITLB, %g3
14 andcc %g5, %g4, %g0 ! Executable? 15 andcc %g5, %g4, %g0 ! Executable?
@@ -16,7 +17,6 @@
16 nop ! Delay slot, fill me 17 nop ! Delay slot, fill me
17 stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB 18 stxa %g5, [%g0] ASI_ITLB_DATA_IN ! Load TLB
18 retry ! Trap done 19 retry ! Trap done
19 nop
20 20
21/* ITLB ** ICACHE line 3: */ 21/* ITLB ** ICACHE line 3: */
22 nop 22 nop
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index 2d333ab4b91..47dfd45971e 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -131,16 +131,8 @@ kvmap_dtlb_4v:
131 brgez,pn %g4, kvmap_dtlb_nonlinear 131 brgez,pn %g4, kvmap_dtlb_nonlinear
132 nop 132 nop
133 133
134#define KERN_HIGHBITS ((_PAGE_VALID|_PAGE_SZ4MB)^0xfffff80000000000) 134 sethi %hi(kern_linear_pte_xor), %g2
135#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) 135 ldx [%g2 + %lo(kern_linear_pte_xor)], %g2
136
137 sethi %uhi(KERN_HIGHBITS), %g2
138 or %g2, %ulo(KERN_HIGHBITS), %g2
139 sllx %g2, 32, %g2
140 or %g2, KERN_LOWBITS, %g2
141
142#undef KERN_HIGHBITS
143#undef KERN_LOWBITS
144 136
145 .globl kvmap_linear_patch 137 .globl kvmap_linear_patch
146kvmap_linear_patch: 138kvmap_linear_patch:
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index f36b257b2e4..ca75f3b26a3 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
diff --git a/arch/sparc64/kernel/sun4v_tlb_miss.S b/arch/sparc64/kernel/sun4v_tlb_miss.S
index 597359ced23..950ca74b4a5 100644
--- a/arch/sparc64/kernel/sun4v_tlb_miss.S
+++ b/arch/sparc64/kernel/sun4v_tlb_miss.S
@@ -59,7 +59,8 @@ sun4v_itlb_miss:
59 /* Load TSB tag/pte into %g2/%g3 and compare the tag. */ 59 /* Load TSB tag/pte into %g2/%g3 and compare the tag. */
60 ldda [%g1] ASI_QUAD_LDD_PHYS, %g2 60 ldda [%g1] ASI_QUAD_LDD_PHYS, %g2
61 cmp %g2, %g6 61 cmp %g2, %g6
62 sethi %hi(_PAGE_EXEC), %g7 62 sethi %hi(PAGE_EXEC), %g7
63 ldx [%g7 + %lo(PAGE_EXEC)], %g7
63 bne,a,pn %xcc, tsb_miss_page_table_walk 64 bne,a,pn %xcc, tsb_miss_page_table_walk
64 mov FAULT_CODE_ITLB, %g3 65 mov FAULT_CODE_ITLB, %g3
65 andcc %g3, %g7, %g0 66 andcc %g3, %g7, %g0
diff --git a/arch/sparc64/kernel/tsb.S b/arch/sparc64/kernel/tsb.S
index 667dcb077be..be8f0892d72 100644
--- a/arch/sparc64/kernel/tsb.S
+++ b/arch/sparc64/kernel/tsb.S
@@ -56,10 +56,11 @@ tsb_reload:
56 /* If it is larger than the base page size, don't 56 /* If it is larger than the base page size, don't
57 * bother putting it into the TSB. 57 * bother putting it into the TSB.
58 */ 58 */
59 srlx %g5, 32, %g2 59 sethi %hi(_PAGE_ALL_SZ_BITS), %g7
60 sethi %hi(_PAGE_ALL_SZ_BITS >> 32), %g7 60 ldx [%g7 + %lo(_PAGE_ALL_SZ_BITS)], %g7
61 and %g2, %g7, %g2 61 and %g5, %g7, %g2
62 sethi %hi(_PAGE_SZBITS >> 32), %g7 62 sethi %hi(_PAGE_SZBITS), %g7
63 ldx [%g7 + %lo(_PAGE_SZBITS)], %g7
63 cmp %g2, %g7 64 cmp %g2, %g7
64 bne,a,pn %xcc, tsb_tlb_reload 65 bne,a,pn %xcc, tsb_tlb_reload
65 TSB_STORE(%g1, %g0) 66 TSB_STORE(%g1, %g0)