aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/cpu.c18
-rw-r--r--arch/sparc/kernel/entry.S10
-rw-r--r--arch/sparc/kernel/etrap_32.S18
-rw-r--r--arch/sparc/kernel/head_32.S168
-rw-r--r--arch/sparc/kernel/ioport.c24
-rw-r--r--arch/sparc/kernel/irq_32.c22
-rw-r--r--arch/sparc/kernel/kernel.h3
-rw-r--r--arch/sparc/kernel/leon_kernel.c1
-rw-r--r--arch/sparc/kernel/leon_pmc.c15
-rw-r--r--arch/sparc/kernel/leon_smp.c8
-rw-r--r--arch/sparc/kernel/process_32.c35
-rw-r--r--arch/sparc/kernel/prom_common.c1
-rw-r--r--arch/sparc/kernel/rtrap_32.S18
-rw-r--r--arch/sparc/kernel/setup_32.c62
-rw-r--r--arch/sparc/kernel/signal_32.c2
-rw-r--r--arch/sparc/kernel/signal_64.c2
-rw-r--r--arch/sparc/kernel/trampoline_32.S6
-rw-r--r--arch/sparc/kernel/traps_64.c12
-rw-r--r--arch/sparc/kernel/vmlinux.lds.S5
-rw-r--r--arch/sparc/kernel/wof.S18
-rw-r--r--arch/sparc/kernel/wuf.S27
22 files changed, 273 insertions, 206 deletions
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index 72308f9b0096..6cf591b7e1c6 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -51,8 +51,8 @@ obj-y += of_device_common.o
51obj-y += of_device_$(BITS).o 51obj-y += of_device_$(BITS).o
52obj-$(CONFIG_SPARC64) += prom_irqtrans.o 52obj-$(CONFIG_SPARC64) += prom_irqtrans.o
53 53
54obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o 54obj-$(CONFIG_SPARC32) += leon_kernel.o
55obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o 55obj-$(CONFIG_SPARC32) += leon_pmc.o
56 56
57obj-$(CONFIG_SPARC64) += reboot.o 57obj-$(CONFIG_SPARC64) += reboot.o
58obj-$(CONFIG_SPARC64) += sysfs.o 58obj-$(CONFIG_SPARC64) += sysfs.o
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 2d1819641769..a6c94a2bf9d4 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -121,7 +121,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
121 FPU(-1, NULL) 121 FPU(-1, NULL)
122 } 122 }
123},{ 123},{
124 4, 124 PSR_IMPL_TI,
125 .cpu_info = { 125 .cpu_info = {
126 CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), 126 CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"),
127 /* SparcClassic -- borned STP1010TAB-50*/ 127 /* SparcClassic -- borned STP1010TAB-50*/
@@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = {
191 FPU(-1, NULL) 191 FPU(-1, NULL)
192 } 192 }
193},{ 193},{
194 0xF, /* Aeroflex Gaisler */ 194 PSR_IMPL_LEON, /* Aeroflex Gaisler */
195 .cpu_info = { 195 .cpu_info = {
196 CPU(3, "LEON"), 196 CPU(3, "LEON"),
197 CPU(-1, NULL) 197 CPU(-1, NULL)
@@ -440,16 +440,16 @@ static int __init cpu_type_probe(void)
440 int psr_impl, psr_vers, fpu_vers; 440 int psr_impl, psr_vers, fpu_vers;
441 int psr; 441 int psr;
442 442
443 psr_impl = ((get_psr() >> 28) & 0xf); 443 psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK);
444 psr_vers = ((get_psr() >> 24) & 0xf); 444 psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK);
445 445
446 psr = get_psr(); 446 psr = get_psr();
447 put_psr(psr | PSR_EF); 447 put_psr(psr | PSR_EF);
448#ifdef CONFIG_SPARC_LEON 448
449 fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; 449 if (psr_impl == PSR_IMPL_LEON)
450#else 450 fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7;
451 fpu_vers = ((get_fsr() >> 17) & 0x7); 451 else
452#endif 452 fpu_vers = ((get_fsr() >> 17) & 0x7);
453 453
454 put_psr(psr); 454 put_psr(psr);
455 455
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 2dbe1806e530..dcaa1cf0de40 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -393,7 +393,6 @@ linux_trap_ipi15_sun4d:
393 /* FIXME */ 393 /* FIXME */
3941: b,a 1b 3941: b,a 1b
395 395
396#ifdef CONFIG_SPARC_LEON
397 .globl smpleon_ipi 396 .globl smpleon_ipi
398 .extern leon_ipi_interrupt 397 .extern leon_ipi_interrupt
399 /* SMP per-cpu IPI interrupts are handled specially. */ 398 /* SMP per-cpu IPI interrupts are handled specially. */
@@ -424,8 +423,6 @@ linux_trap_ipi15_leon:
424 b ret_trap_lockless_ipi 423 b ret_trap_lockless_ipi
425 clr %l6 424 clr %l6
426 425
427#endif /* CONFIG_SPARC_LEON */
428
429#endif /* CONFIG_SMP */ 426#endif /* CONFIG_SMP */
430 427
431 /* This routine handles illegal instructions and privileged 428 /* This routine handles illegal instructions and privileged
@@ -770,8 +767,11 @@ srmmu_fault:
770 mov 0x400, %l5 767 mov 0x400, %l5
771 mov 0x300, %l4 768 mov 0x300, %l4
772 769
773 lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first 770LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first
774 lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last 771SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first
772
773LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last
774SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last
775 775
776 andn %l6, 0xfff, %l6 776 andn %l6, 0xfff, %l6
777 srl %l5, 6, %l5 ! and encode all info into l7 777 srl %l5, 6, %l5 ! and encode all info into l7
diff --git a/arch/sparc/kernel/etrap_32.S b/arch/sparc/kernel/etrap_32.S
index 84b5f0d2afde..e3e80d65e39a 100644
--- a/arch/sparc/kernel/etrap_32.S
+++ b/arch/sparc/kernel/etrap_32.S
@@ -234,7 +234,8 @@ tsetup_srmmu_stackchk:
234 234
235 cmp %glob_tmp, %sp 235 cmp %glob_tmp, %sp
236 bleu,a 1f 236 bleu,a 1f
237 lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control 237LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
238SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
238 239
239trap_setup_user_stack_is_bolixed: 240trap_setup_user_stack_is_bolixed:
240 /* From user/kernel into invalid window w/bad user 241 /* From user/kernel into invalid window w/bad user
@@ -249,18 +250,25 @@ trap_setup_user_stack_is_bolixed:
2491: 2501:
250 /* Clear the fault status and turn on the no_fault bit. */ 251 /* Clear the fault status and turn on the no_fault bit. */
251 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit 252 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
252 sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it 253LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
254SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
253 255
254 /* Dump the registers and cross fingers. */ 256 /* Dump the registers and cross fingers. */
255 STORE_WINDOW(sp) 257 STORE_WINDOW(sp)
256 258
257 /* Clear the no_fault bit and check the status. */ 259 /* Clear the no_fault bit and check the status. */
258 andn %glob_tmp, 0x2, %glob_tmp 260 andn %glob_tmp, 0x2, %glob_tmp
259 sta %glob_tmp, [%g0] ASI_M_MMUREGS 261LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
262SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
263
260 mov AC_M_SFAR, %glob_tmp 264 mov AC_M_SFAR, %glob_tmp
261 lda [%glob_tmp] ASI_M_MMUREGS, %g0 265LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
266SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
267
262 mov AC_M_SFSR, %glob_tmp 268 mov AC_M_SFSR, %glob_tmp
263 lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore 269LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore
270SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore
271
264 andcc %glob_tmp, 0x2, %g0 ! did we fault? 272 andcc %glob_tmp, 0x2, %g0 ! did we fault?
265 bne trap_setup_user_stack_is_bolixed ! failure 273 bne trap_setup_user_stack_is_bolixed ! failure
266 nop 274 nop
diff --git a/arch/sparc/kernel/head_32.S b/arch/sparc/kernel/head_32.S
index a0f5c20e4b9c..afeb1d770303 100644
--- a/arch/sparc/kernel/head_32.S
+++ b/arch/sparc/kernel/head_32.S
@@ -30,10 +30,6 @@
30 * the cpu-type 30 * the cpu-type
31 */ 31 */
32 .align 4 32 .align 4
33cputyp:
34 .word 1
35
36 .align 4
37 .globl cputypval 33 .globl cputypval
38cputypval: 34cputypval:
39 .asciz "sun4m" 35 .asciz "sun4m"
@@ -46,8 +42,8 @@ cputypvar:
46 42
47 .align 4 43 .align 4
48 44
49sun4c_notsup: 45notsup:
50 .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" 46 .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n"
51 .align 4 47 .align 4
52 48
53sun4e_notsup: 49sun4e_notsup:
@@ -123,7 +119,7 @@ current_pc:
123 tst %o0 119 tst %o0
124 be no_sun4u_here 120 be no_sun4u_here
125 mov %g4, %o7 /* Previous %o7. */ 121 mov %g4, %o7 /* Previous %o7. */
126 122
127 mov %o0, %l0 ! stash away romvec 123 mov %o0, %l0 ! stash away romvec
128 mov %o0, %g7 ! put it here too 124 mov %o0, %g7 ! put it here too
129 mov %o1, %l1 ! stash away debug_vec too 125 mov %o1, %l1 ! stash away debug_vec too
@@ -132,7 +128,7 @@ current_pc:
132 set current_pc, %g5 128 set current_pc, %g5
133 cmp %g3, %g5 129 cmp %g3, %g5
134 be already_mapped 130 be already_mapped
135 nop 131 nop
136 132
137 /* %l6 will hold the offset we have to subtract 133 /* %l6 will hold the offset we have to subtract
138 * from absolute symbols in order to access areas 134 * from absolute symbols in order to access areas
@@ -192,9 +188,9 @@ copy_prom_done:
192 bne not_a_sun4 188 bne not_a_sun4
193 nop 189 nop
194 190
195halt_sun4_or_sun4c: 191halt_notsup:
196 ld [%g7 + 0x68], %o1 192 ld [%g7 + 0x68], %o1
197 set sun4c_notsup, %o0 193 set notsup, %o0
198 sub %o0, %l6, %o0 194 sub %o0, %l6, %o0
199 call %o1 195 call %o1
200 nop 196 nop
@@ -202,18 +198,31 @@ halt_sun4_or_sun4c:
202 nop 198 nop
203 199
204not_a_sun4: 200not_a_sun4:
201 /* It looks like this is a machine we support.
202 * Now find out what MMU we are dealing with
203 * LEON - identified by the psr.impl field
204 * Viking - identified by the psr.impl field
205 * In all other cases a sun4m srmmu.
206 * We check that the MMU is enabled in all cases.
207 */
208
209 /* Check if this is a LEON CPU */
210 rd %psr, %g3
211 srl %g3, PSR_IMPL_SHIFT, %g3
212 and %g3, PSR_IMPL_SHIFTED_MASK, %g3
213 cmp %g3, PSR_IMPL_LEON
214 be leon_remap /* It is a LEON - jump */
215 nop
216
217 /* Sanity-check, is MMU enabled */
205 lda [%g0] ASI_M_MMUREGS, %g1 218 lda [%g0] ASI_M_MMUREGS, %g1
206 andcc %g1, 1, %g0 219 andcc %g1, 1, %g0
207 be halt_sun4_or_sun4c 220 be halt_notsup
208 nop 221 nop
209 222
210srmmu_remap: 223 /* Check for a viking (TI) module. */
211 /* First, check for a viking (TI) module. */ 224 cmp %g3, PSR_IMPL_TI
212 set 0x40000000, %g2 225 bne srmmu_not_viking
213 rd %psr, %g3
214 and %g2, %g3, %g3
215 subcc %g3, 0x0, %g0
216 bz srmmu_nviking
217 nop 226 nop
218 227
219 /* Figure out what kind of viking we are on. 228 /* Figure out what kind of viking we are on.
@@ -228,14 +237,14 @@ srmmu_remap:
228 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg 237 lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg
229 and %g2, %g3, %g3 238 and %g2, %g3, %g3
230 subcc %g3, 0x0, %g0 239 subcc %g3, 0x0, %g0
231 bnz srmmu_nviking ! is in mbus mode 240 bnz srmmu_not_viking ! is in mbus mode
232 nop 241 nop
233 242
234 rd %psr, %g3 ! DO NOT TOUCH %g3 243 rd %psr, %g3 ! DO NOT TOUCH %g3
235 andn %g3, PSR_ET, %g2 244 andn %g3, PSR_ET, %g2
236 wr %g2, 0x0, %psr 245 wr %g2, 0x0, %psr
237 WRITE_PAUSE 246 WRITE_PAUSE
238 247
239 /* Get context table pointer, then convert to 248 /* Get context table pointer, then convert to
240 * a physical address, which is 36 bits. 249 * a physical address, which is 36 bits.
241 */ 250 */
@@ -258,12 +267,12 @@ srmmu_remap:
258 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr 267 lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr
259 srl %o1, 0x4, %o1 ! Clear low 4 bits 268 srl %o1, 0x4, %o1 ! Clear low 4 bits
260 sll %o1, 0x8, %o1 ! Make physical 269 sll %o1, 0x8, %o1 ! Make physical
261 270
262 /* Ok, pull in the PTD. */ 271 /* Ok, pull in the PTD. */
263 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd 272 lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd
264 273
265 /* Calculate to KERNBASE entry. */ 274 /* Calculate to KERNBASE entry. */
266 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 275 add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3
267 276
268 /* Poke the entry into the calculated address. */ 277 /* Poke the entry into the calculated address. */
269 sta %o2, [%o3] ASI_M_BYPASS 278 sta %o2, [%o3] ASI_M_BYPASS
@@ -293,12 +302,12 @@ srmmu_remap:
293 b go_to_highmem 302 b go_to_highmem
294 nop 303 nop
295 304
305srmmu_not_viking:
296 /* This works on viking's in Mbus mode and all 306 /* This works on viking's in Mbus mode and all
297 * other MBUS modules. It is virtually the same as 307 * other MBUS modules. It is virtually the same as
298 * the above madness sans turning traps off and flipping 308 * the above madness sans turning traps off and flipping
299 * the AC bit. 309 * the AC bit.
300 */ 310 */
301srmmu_nviking:
302 set AC_M_CTPR, %g1 311 set AC_M_CTPR, %g1
303 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr 312 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr
304 sll %g1, 0x4, %g1 ! make physical addr 313 sll %g1, 0x4, %g1 ! make physical addr
@@ -313,6 +322,29 @@ srmmu_nviking:
313 nop ! wheee.... 322 nop ! wheee....
314 323
315 324
325leon_remap:
326 /* Sanity-check, is MMU enabled */
327 lda [%g0] ASI_LEON_MMUREGS, %g1
328 andcc %g1, 1, %g0
329 be halt_notsup
330 nop
331
332 /* Same code as in the srmmu_not_viking case,
333 * with the LEON ASI for mmuregs
334 */
335 set AC_M_CTPR, %g1
336 lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr
337 sll %g1, 0x4, %g1 ! make physical addr
338 lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table
339 srl %g1, 0x4, %g1
340 sll %g1, 0x8, %g1 ! make phys addr for l1 tbl
341
342 lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0
343 add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3
344 sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry
345 b go_to_highmem
346 nop ! wheee....
347
316/* Now do a non-relative jump so that PC is in high-memory */ 348/* Now do a non-relative jump so that PC is in high-memory */
317go_to_highmem: 349go_to_highmem:
318 set execute_in_high_mem, %g1 350 set execute_in_high_mem, %g1
@@ -336,8 +368,9 @@ execute_in_high_mem:
336 sethi %hi(linux_dbvec), %g1 368 sethi %hi(linux_dbvec), %g1
337 st %o1, [%g1 + %lo(linux_dbvec)] 369 st %o1, [%g1 + %lo(linux_dbvec)]
338 370
339/* Get the machine type via the mysterious romvec node operations. */ 371 /* Get the machine type via the romvec
340 372 * getprops node operation
373 */
341 add %g7, 0x1c, %l1 374 add %g7, 0x1c, %l1
342 ld [%l1], %l0 375 ld [%l1], %l0
343 ld [%l0], %l0 376 ld [%l0], %l0
@@ -356,9 +389,42 @@ execute_in_high_mem:
356 ! to a buf where above string 389 ! to a buf where above string
357 ! will get stored by the prom. 390 ! will get stored by the prom.
358 391
359#ifdef CONFIG_SPARC_LEON
360 /* no cpu-type check is needed, it is a SPARC-LEON */
361 392
393 /* Check value of "compatible" property.
394 * "value" => "model"
395 * leon => sparc_leon
396 * sun4m => sun4m
397 * sun4s => sun4m
398 * sun4d => sun4d
399 * sun4e => "no_sun4e_here"
400 * '*' => "no_sun4u_here"
401 * Check single letters only
402 */
403
404 set cputypval, %o2
405 /* If cputypval[0] == 'l' (lower case letter L) this is leon */
406 ldub [%o2], %l1
407 cmp %l1, 'l'
408 be leon_init
409 nop
410
411 /* Check cputypval[4] to find the sun model */
412 ldub [%o2 + 0x4], %l1
413
414 cmp %l1, 'm'
415 be sun4m_init
416 cmp %l1, 's'
417 be sun4m_init
418 cmp %l1, 'd'
419 be sun4d_init
420 cmp %l1, 'e'
421 be no_sun4e_here ! Could be a sun4e.
422 nop
423 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
424 nop
425
426leon_init:
427 /* LEON CPU - set boot_cpu_id */
362 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index 428 sethi %hi(boot_cpu_id), %g2 ! boot-cpu index
363 429
364#ifdef CONFIG_SMP 430#ifdef CONFIG_SMP
@@ -376,26 +442,6 @@ execute_in_high_mem:
376 442
377 ba continue_boot 443 ba continue_boot
378 nop 444 nop
379#endif
380
381/* Check to cputype. We may be booted on a sun4u (64 bit box),
382 * and sun4d needs special treatment.
383 */
384
385 set cputypval, %o2
386 ldub [%o2 + 0x4], %l1
387
388 cmp %l1, 'm'
389 be sun4m_init
390 cmp %l1, 's'
391 be sun4m_init
392 cmp %l1, 'd'
393 be sun4d_init
394 cmp %l1, 'e'
395 be no_sun4e_here ! Could be a sun4e.
396 nop
397 b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :))
398 nop
399 445
400/* CPUID in bootbus can be found at PA 0xff0140000 */ 446/* CPUID in bootbus can be found at PA 0xff0140000 */
401#define SUN4D_BOOTBUS_CPUID 0xf0140000 447#define SUN4D_BOOTBUS_CPUID 0xf0140000
@@ -431,9 +477,9 @@ sun4m_init:
431/* This sucks, apparently this makes Vikings call prom panic, will fix later */ 477/* This sucks, apparently this makes Vikings call prom panic, will fix later */
4322: 4782:
433 rd %psr, %o1 479 rd %psr, %o1
434 srl %o1, 28, %o1 ! Get a type of the CPU 480 srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU
435 481
436 subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC 482 subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC
437 be continue_boot 483 be continue_boot
438 nop 484 nop
439 485
@@ -459,10 +505,6 @@ continue_boot:
459/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's 505/* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's
460 * show-time! 506 * show-time!
461 */ 507 */
462
463 sethi %hi(cputyp), %o0
464 st %g4, [%o0 + %lo(cputyp)]
465
466 /* Turn on Supervisor, EnableFloating, and all the PIL bits. 508 /* Turn on Supervisor, EnableFloating, and all the PIL bits.
467 * Also puts us in register window zero with traps off. 509 * Also puts us in register window zero with traps off.
468 */ 510 */
@@ -480,7 +522,7 @@ continue_boot:
480 set __bss_start , %o0 ! First address of BSS 522 set __bss_start , %o0 ! First address of BSS
481 set _end , %o1 ! Last address of BSS 523 set _end , %o1 ! Last address of BSS
482 add %o0, 0x1, %o0 524 add %o0, 0x1, %o0
4831: 5251:
484 stb %g0, [%o0] 526 stb %g0, [%o0]
485 subcc %o0, %o1, %g0 527 subcc %o0, %o1, %g0
486 bl 1b 528 bl 1b
@@ -546,7 +588,7 @@ continue_boot:
546 set dest, %g2; \ 588 set dest, %g2; \
547 ld [%g5], %g4; \ 589 ld [%g5], %g4; \
548 st %g4, [%g2]; 590 st %g4, [%g2];
549 591
550 /* Patch for window spills... */ 592 /* Patch for window spills... */
551 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) 593 PATCH_INSN(spnwin_patch1_7win, spnwin_patch1)
552 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) 594 PATCH_INSN(spnwin_patch2_7win, spnwin_patch2)
@@ -597,7 +639,7 @@ continue_boot:
597 st %g4, [%g5 + 0x18] 639 st %g4, [%g5 + 0x18]
598 st %g4, [%g5 + 0x1c] 640 st %g4, [%g5 + 0x1c]
599 641
6002: 6422:
601 sethi %hi(nwindows), %g4 643 sethi %hi(nwindows), %g4
602 st %g3, [%g4 + %lo(nwindows)] ! store final value 644 st %g3, [%g4 + %lo(nwindows)] ! store final value
603 sub %g3, 0x1, %g3 645 sub %g3, 0x1, %g3
@@ -617,18 +659,12 @@ continue_boot:
617 wr %g3, PSR_ET, %psr 659 wr %g3, PSR_ET, %psr
618 WRITE_PAUSE 660 WRITE_PAUSE
619 661
620 /* First we call prom_init() to set up PROMLIB, then 662 /* Call sparc32_start_kernel(struct linux_romvec *rp) */
621 * off to start_kernel().
622 */
623
624 sethi %hi(prom_vector_p), %g5 663 sethi %hi(prom_vector_p), %g5
625 ld [%g5 + %lo(prom_vector_p)], %o0 664 ld [%g5 + %lo(prom_vector_p)], %o0
626 call prom_init 665 call sparc32_start_kernel
627 nop 666 nop
628 667
629 call start_kernel
630 nop
631
632 /* We should not get here. */ 668 /* We should not get here. */
633 call halt_me 669 call halt_me
634 nop 670 nop
@@ -659,7 +695,7 @@ sun4u_5:
659 .asciz "write" 695 .asciz "write"
660 .align 4 696 .align 4
661sun4u_6: 697sun4u_6:
662 .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" 698 .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r"
663sun4u_6e: 699sun4u_6e:
664 .align 4 700 .align 4
665sun4u_7: 701sun4u_7:
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index a2846f5e32d8..0f094db918c7 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -55,17 +55,13 @@ const struct sparc32_dma_ops *sparc32_dma_ops;
55/* This function must make sure that caches and memory are coherent after DMA 55/* This function must make sure that caches and memory are coherent after DMA
56 * On LEON systems without cache snooping it flushes the entire D-CACHE. 56 * On LEON systems without cache snooping it flushes the entire D-CACHE.
57 */ 57 */
58#ifndef CONFIG_SPARC_LEON
59static inline void dma_make_coherent(unsigned long pa, unsigned long len) 58static inline void dma_make_coherent(unsigned long pa, unsigned long len)
60{ 59{
60 if (sparc_cpu_model == sparc_leon) {
61 if (!sparc_leon3_snooping_enabled())
62 leon_flush_dcache_all();
63 }
61} 64}
62#else
63static inline void dma_make_coherent(unsigned long pa, unsigned long len)
64{
65 if (!sparc_leon3_snooping_enabled())
66 leon_flush_dcache_all();
67}
68#endif
69 65
70static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); 66static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz);
71static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, 67static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys,
@@ -427,9 +423,6 @@ arch_initcall(sparc_register_ioport);
427#endif /* CONFIG_SBUS */ 423#endif /* CONFIG_SBUS */
428 424
429 425
430/* LEON reuses PCI DMA ops */
431#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON)
432
433/* Allocate and map kernel buffer using consistent mode DMA for a device. 426/* Allocate and map kernel buffer using consistent mode DMA for a device.
434 * hwdev should be valid struct pci_dev pointer for PCI devices. 427 * hwdev should be valid struct pci_dev pointer for PCI devices.
435 */ 428 */
@@ -657,14 +650,11 @@ struct dma_map_ops pci32_dma_ops = {
657}; 650};
658EXPORT_SYMBOL(pci32_dma_ops); 651EXPORT_SYMBOL(pci32_dma_ops);
659 652
660#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ 653/* leon re-uses pci32_dma_ops */
654struct dma_map_ops *leon_dma_ops = &pci32_dma_ops;
655EXPORT_SYMBOL(leon_dma_ops);
661 656
662#ifdef CONFIG_SPARC_LEON
663struct dma_map_ops *dma_ops = &pci32_dma_ops;
664#elif defined(CONFIG_SBUS)
665struct dma_map_ops *dma_ops = &sbus_dma_ops; 657struct dma_map_ops *dma_ops = &sbus_dma_ops;
666#endif
667
668EXPORT_SYMBOL(dma_ops); 658EXPORT_SYMBOL(dma_ops);
669 659
670 660
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index ae04914f7774..c145f6fd123b 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -241,9 +241,6 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
241 unsigned int cpu_irq; 241 unsigned int cpu_irq;
242 int err; 242 int err;
243 243
244#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON
245 struct tt_entry *trap_table;
246#endif
247 244
248 err = request_irq(irq, irq_handler, 0, "floppy", NULL); 245 err = request_irq(irq, irq_handler, 0, "floppy", NULL);
249 if (err) 246 if (err)
@@ -264,13 +261,18 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler)
264 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; 261 table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP;
265 262
266 INSTANTIATE(sparc_ttable) 263 INSTANTIATE(sparc_ttable)
267#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON 264
268 trap_table = &trapbase_cpu1; 265#if defined CONFIG_SMP
269 INSTANTIATE(trap_table) 266 if (sparc_cpu_model != sparc_leon) {
270 trap_table = &trapbase_cpu2; 267 struct tt_entry *trap_table;
271 INSTANTIATE(trap_table) 268
272 trap_table = &trapbase_cpu3; 269 trap_table = &trapbase_cpu1;
273 INSTANTIATE(trap_table) 270 INSTANTIATE(trap_table)
271 trap_table = &trapbase_cpu2;
272 INSTANTIATE(trap_table)
273 trap_table = &trapbase_cpu3;
274 INSTANTIATE(trap_table)
275 }
274#endif 276#endif
275#undef INSTANTIATE 277#undef INSTANTIATE
276 /* 278 /*
diff --git a/arch/sparc/kernel/kernel.h b/arch/sparc/kernel/kernel.h
index a86372d34587..291bb5de9ce0 100644
--- a/arch/sparc/kernel/kernel.h
+++ b/arch/sparc/kernel/kernel.h
@@ -26,6 +26,9 @@ static inline unsigned long kimage_addr_to_ra(const char *p)
26#endif 26#endif
27 27
28#ifdef CONFIG_SPARC32 28#ifdef CONFIG_SPARC32
29/* setup_32.c */
30void sparc32_start_kernel(struct linux_romvec *rp);
31
29/* cpu.c */ 32/* cpu.c */
30extern void cpu_probe(void); 33extern void cpu_probe(void);
31 34
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c
index 77c1b916e4dd..e34e2c40c060 100644
--- a/arch/sparc/kernel/leon_kernel.c
+++ b/arch/sparc/kernel/leon_kernel.c
@@ -23,6 +23,7 @@
23#include <asm/smp.h> 23#include <asm/smp.h>
24#include <asm/setup.h> 24#include <asm/setup.h>
25 25
26#include "kernel.h"
26#include "prom.h" 27#include "prom.h"
27#include "irq.h" 28#include "irq.h"
28 29
diff --git a/arch/sparc/kernel/leon_pmc.c b/arch/sparc/kernel/leon_pmc.c
index 519ca923f59f..4e174321097d 100644
--- a/arch/sparc/kernel/leon_pmc.c
+++ b/arch/sparc/kernel/leon_pmc.c
@@ -7,6 +7,7 @@
7#include <linux/pm.h> 7#include <linux/pm.h>
8 8
9#include <asm/leon_amba.h> 9#include <asm/leon_amba.h>
10#include <asm/cpu_type.h>
10#include <asm/leon.h> 11#include <asm/leon.h>
11 12
12/* List of Systems that need fixup instructions around power-down instruction */ 13/* List of Systems that need fixup instructions around power-down instruction */
@@ -65,13 +66,15 @@ void pmc_leon_idle(void)
65/* Install LEON Power Down function */ 66/* Install LEON Power Down function */
66static int __init leon_pmc_install(void) 67static int __init leon_pmc_install(void)
67{ 68{
68 /* Assign power management IDLE handler */ 69 if (sparc_cpu_model == sparc_leon) {
69 if (pmc_leon_need_fixup()) 70 /* Assign power management IDLE handler */
70 pm_idle = pmc_leon_idle_fixup; 71 if (pmc_leon_need_fixup())
71 else 72 pm_idle = pmc_leon_idle_fixup;
72 pm_idle = pmc_leon_idle; 73 else
74 pm_idle = pmc_leon_idle;
73 75
74 printk(KERN_INFO "leon: power management initialized\n"); 76 printk(KERN_INFO "leon: power management initialized\n");
77 }
75 78
76 return 0; 79 return 0;
77} 80}
diff --git a/arch/sparc/kernel/leon_smp.c b/arch/sparc/kernel/leon_smp.c
index a469090faf9f..0f3fb6d9c8ef 100644
--- a/arch/sparc/kernel/leon_smp.c
+++ b/arch/sparc/kernel/leon_smp.c
@@ -48,15 +48,13 @@
48 48
49#include "kernel.h" 49#include "kernel.h"
50 50
51#ifdef CONFIG_SPARC_LEON
52
53#include "irq.h" 51#include "irq.h"
54 52
55extern ctxd_t *srmmu_ctx_table_phys; 53extern ctxd_t *srmmu_ctx_table_phys;
56static int smp_processors_ready; 54static int smp_processors_ready;
57extern volatile unsigned long cpu_callin_map[NR_CPUS]; 55extern volatile unsigned long cpu_callin_map[NR_CPUS];
58extern cpumask_t smp_commenced_mask; 56extern cpumask_t smp_commenced_mask;
59void __init leon_configure_cache_smp(void); 57void __cpuinit leon_configure_cache_smp(void);
60static void leon_ipi_init(void); 58static void leon_ipi_init(void);
61 59
62/* IRQ number of LEON IPIs */ 60/* IRQ number of LEON IPIs */
@@ -123,7 +121,7 @@ void __cpuinit leon_callin(void)
123 121
124extern struct linux_prom_registers smp_penguin_ctable; 122extern struct linux_prom_registers smp_penguin_ctable;
125 123
126void __init leon_configure_cache_smp(void) 124void __cpuinit leon_configure_cache_smp(void)
127{ 125{
128 unsigned long cfg = sparc_leon3_get_dcachecfg(); 126 unsigned long cfg = sparc_leon3_get_dcachecfg();
129 int me = smp_processor_id(); 127 int me = smp_processor_id();
@@ -507,5 +505,3 @@ void __init leon_init_smp(void)
507 505
508 sparc32_ipi_ops = &leon_ipi_ops; 506 sparc32_ipi_ops = &leon_ipi_ops;
509} 507}
510
511#endif /* CONFIG_SPARC_LEON */
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index fe6787cc62fc..cb36e82dcd5d 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -65,50 +65,25 @@ extern void fpsave(unsigned long *, unsigned long *, void *, unsigned long *);
65struct task_struct *last_task_used_math = NULL; 65struct task_struct *last_task_used_math = NULL;
66struct thread_info *current_set[NR_CPUS]; 66struct thread_info *current_set[NR_CPUS];
67 67
68#ifndef CONFIG_SMP
69
70/* 68/*
71 * the idle loop on a Sparc... ;) 69 * the idle loop on a Sparc... ;)
72 */ 70 */
73void cpu_idle(void) 71void cpu_idle(void)
74{ 72{
75 /* endless idle loop with no priority at all */ 73 set_thread_flag(TIF_POLLING_NRFLAG);
76 for (;;) {
77 if (pm_idle) {
78 while (!need_resched())
79 (*pm_idle)();
80 } else {
81 while (!need_resched())
82 cpu_relax();
83 }
84 schedule_preempt_disabled();
85 }
86}
87
88#else
89 74
90/* This is being executed in task 0 'user space'. */
91void cpu_idle(void)
92{
93 set_thread_flag(TIF_POLLING_NRFLAG);
94 /* endless idle loop with no priority at all */ 75 /* endless idle loop with no priority at all */
95 while(1) { 76 for (;;) {
96#ifdef CONFIG_SPARC_LEON 77 while (!need_resched()) {
97 if (pm_idle) { 78 if (pm_idle)
98 while (!need_resched())
99 (*pm_idle)(); 79 (*pm_idle)();
100 } else 80 else
101#endif
102 {
103 while (!need_resched())
104 cpu_relax(); 81 cpu_relax();
105 } 82 }
106 schedule_preempt_disabled(); 83 schedule_preempt_disabled();
107 } 84 }
108} 85}
109 86
110#endif
111
112/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ 87/* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */
113void machine_halt(void) 88void machine_halt(void)
114{ 89{
diff --git a/arch/sparc/kernel/prom_common.c b/arch/sparc/kernel/prom_common.c
index 741df916c124..1303021748c8 100644
--- a/arch/sparc/kernel/prom_common.c
+++ b/arch/sparc/kernel/prom_common.c
@@ -23,7 +23,6 @@
23#include <linux/of_pdt.h> 23#include <linux/of_pdt.h>
24#include <asm/prom.h> 24#include <asm/prom.h>
25#include <asm/oplib.h> 25#include <asm/oplib.h>
26#include <asm/leon.h>
27 26
28#include "prom.h" 27#include "prom.h"
29 28
diff --git a/arch/sparc/kernel/rtrap_32.S b/arch/sparc/kernel/rtrap_32.S
index 7abc24e2bf1a..6c34de0c2abd 100644
--- a/arch/sparc/kernel/rtrap_32.S
+++ b/arch/sparc/kernel/rtrap_32.S
@@ -231,11 +231,14 @@ srmmu_rett_stackchk:
231 cmp %g1, %fp 231 cmp %g1, %fp
232 bleu ret_trap_user_stack_is_bolixed 232 bleu ret_trap_user_stack_is_bolixed
233 mov AC_M_SFSR, %g1 233 mov AC_M_SFSR, %g1
234 lda [%g1] ASI_M_MMUREGS, %g0 234LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0)
235SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0)
235 236
236 lda [%g0] ASI_M_MMUREGS, %g1 237LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1)
238SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1)
237 or %g1, 0x2, %g1 239 or %g1, 0x2, %g1
238 sta %g1, [%g0] ASI_M_MMUREGS 240LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
241SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
239 242
240 restore %g0, %g0, %g0 243 restore %g0, %g0, %g0
241 244
@@ -244,13 +247,16 @@ srmmu_rett_stackchk:
244 save %g0, %g0, %g0 247 save %g0, %g0, %g0
245 248
246 andn %g1, 0x2, %g1 249 andn %g1, 0x2, %g1
247 sta %g1, [%g0] ASI_M_MMUREGS 250LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS)
251SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS)
248 252
249 mov AC_M_SFAR, %g2 253 mov AC_M_SFAR, %g2
250 lda [%g2] ASI_M_MMUREGS, %g2 254LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2)
255SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2)
251 256
252 mov AC_M_SFSR, %g1 257 mov AC_M_SFSR, %g1
253 lda [%g1] ASI_M_MMUREGS, %g1 258LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1)
259SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1)
254 andcc %g1, 0x2, %g0 260 andcc %g1, 0x2, %g0
255 be ret_trap_userwins_ok 261 be ret_trap_userwins_ok
256 nop 262 nop
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index c052313f4dc5..efe3e64bba38 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -32,6 +32,7 @@
32#include <linux/cpu.h> 32#include <linux/cpu.h>
33#include <linux/kdebug.h> 33#include <linux/kdebug.h>
34#include <linux/export.h> 34#include <linux/export.h>
35#include <linux/start_kernel.h>
35 36
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/processor.h> 38#include <asm/processor.h>
@@ -45,6 +46,7 @@
45#include <asm/cpudata.h> 46#include <asm/cpudata.h>
46#include <asm/setup.h> 47#include <asm/setup.h>
47#include <asm/cacheflush.h> 48#include <asm/cacheflush.h>
49#include <asm/sections.h>
48 50
49#include "kernel.h" 51#include "kernel.h"
50 52
@@ -237,28 +239,42 @@ static void __init per_cpu_patch(void)
237 } 239 }
238} 240}
239 241
242struct leon_1insn_patch_entry {
243 unsigned int addr;
244 unsigned int insn;
245};
246
240enum sparc_cpu sparc_cpu_model; 247enum sparc_cpu sparc_cpu_model;
241EXPORT_SYMBOL(sparc_cpu_model); 248EXPORT_SYMBOL(sparc_cpu_model);
242 249
243struct tt_entry *sparc_ttable; 250static __init void leon_patch(void)
251{
252 struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch;
253 struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end;
244 254
245struct pt_regs fake_swapper_regs; 255 /* Default instruction is leon - no patching */
256 if (sparc_cpu_model == sparc_leon)
257 return;
246 258
247void __init setup_arch(char **cmdline_p) 259 while (start < end) {
248{ 260 unsigned long addr = start->addr;
249 int i;
250 unsigned long highest_paddr;
251 261
252 sparc_ttable = (struct tt_entry *) &trapbase; 262 *(unsigned int *)(addr) = start->insn;
263 flushi(addr);
253 264
254 /* Initialize PROM console and command line. */ 265 start++;
255 *cmdline_p = prom_getbootargs(); 266 }
256 strcpy(boot_command_line, *cmdline_p); 267}
257 parse_early_param();
258 268
259 boot_flags_init(*cmdline_p); 269struct tt_entry *sparc_ttable;
270struct pt_regs fake_swapper_regs;
260 271
261 register_console(&prom_early_console); 272/* Called from head_32.S - before we have setup anything
273 * in the kernel. Be very careful with what you do here.
274 */
275void __init sparc32_start_kernel(struct linux_romvec *rp)
276{
277 prom_init(rp);
262 278
263 /* Set sparc_cpu_model */ 279 /* Set sparc_cpu_model */
264 sparc_cpu_model = sun_unknown; 280 sparc_cpu_model = sun_unknown;
@@ -275,6 +291,26 @@ void __init setup_arch(char **cmdline_p)
275 if (!strncmp(&cputypval[0], "leon" , 4)) 291 if (!strncmp(&cputypval[0], "leon" , 4))
276 sparc_cpu_model = sparc_leon; 292 sparc_cpu_model = sparc_leon;
277 293
294 leon_patch();
295 start_kernel();
296}
297
298void __init setup_arch(char **cmdline_p)
299{
300 int i;
301 unsigned long highest_paddr;
302
303 sparc_ttable = (struct tt_entry *) &trapbase;
304
305 /* Initialize PROM console and command line. */
306 *cmdline_p = prom_getbootargs();
307 strcpy(boot_command_line, *cmdline_p);
308 parse_early_param();
309
310 boot_flags_init(*cmdline_p);
311
312 register_console(&prom_early_console);
313
278 printk("ARCH: "); 314 printk("ARCH: ");
279 switch(sparc_cpu_model) { 315 switch(sparc_cpu_model) {
280 case sun4m: 316 case sun4m:
diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
index 2b7e849f7c65..6b42e8622d12 100644
--- a/arch/sparc/kernel/signal_32.c
+++ b/arch/sparc/kernel/signal_32.c
@@ -590,8 +590,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
590 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 590 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
591 clear_thread_flag(TIF_NOTIFY_RESUME); 591 clear_thread_flag(TIF_NOTIFY_RESUME);
592 tracehook_notify_resume(regs); 592 tracehook_notify_resume(regs);
593 if (current->replacement_session_keyring)
594 key_replace_session_keyring();
595 } 593 }
596} 594}
597 595
diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
index eafaab486b2d..c82cf1cc3965 100644
--- a/arch/sparc/kernel/signal_64.c
+++ b/arch/sparc/kernel/signal_64.c
@@ -607,8 +607,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
607 if (thread_info_flags & _TIF_NOTIFY_RESUME) { 607 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
608 clear_thread_flag(TIF_NOTIFY_RESUME); 608 clear_thread_flag(TIF_NOTIFY_RESUME);
609 tracehook_notify_resume(regs); 609 tracehook_notify_resume(regs);
610 if (current->replacement_session_keyring)
611 key_replace_session_keyring();
612 } 610 }
613} 611}
614 612
diff --git a/arch/sparc/kernel/trampoline_32.S b/arch/sparc/kernel/trampoline_32.S
index 7364ddc9e5aa..af27acab4486 100644
--- a/arch/sparc/kernel/trampoline_32.S
+++ b/arch/sparc/kernel/trampoline_32.S
@@ -149,8 +149,6 @@ sun4d_cpu_startup:
149 149
150 b,a smp_do_cpu_idle 150 b,a smp_do_cpu_idle
151 151
152#ifdef CONFIG_SPARC_LEON
153
154 __CPUINIT 152 __CPUINIT
155 .align 4 153 .align 4
156 .global leon_smp_cpu_startup, smp_penguin_ctable 154 .global leon_smp_cpu_startup, smp_penguin_ctable
@@ -161,7 +159,7 @@ leon_smp_cpu_startup:
161 ld [%g1+4],%g1 159 ld [%g1+4],%g1
162 srl %g1,4,%g1 160 srl %g1,4,%g1
163 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ 161 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */
164 sta %g1, [%g5] ASI_M_MMUREGS 162 sta %g1, [%g5] ASI_LEON_MMUREGS
165 163
166 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ 164 /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */
167 set (PSR_PIL | PSR_S | PSR_PS), %g1 165 set (PSR_PIL | PSR_S | PSR_PS), %g1
@@ -207,5 +205,3 @@ leon_smp_cpu_startup:
207 nop 205 nop
208 206
209 b,a smp_do_cpu_idle 207 b,a smp_do_cpu_idle
210
211#endif
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index c72fdf55e1c1..3b05e6697710 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -2054,7 +2054,7 @@ void do_fpieee(struct pt_regs *regs)
2054 do_fpe_common(regs); 2054 do_fpe_common(regs);
2055} 2055}
2056 2056
2057extern int do_mathemu(struct pt_regs *, struct fpustate *); 2057extern int do_mathemu(struct pt_regs *, struct fpustate *, bool);
2058 2058
2059void do_fpother(struct pt_regs *regs) 2059void do_fpother(struct pt_regs *regs)
2060{ 2060{
@@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs)
2068 switch ((current_thread_info()->xfsr[0] & 0x1c000)) { 2068 switch ((current_thread_info()->xfsr[0] & 0x1c000)) {
2069 case (2 << 14): /* unfinished_FPop */ 2069 case (2 << 14): /* unfinished_FPop */
2070 case (3 << 14): /* unimplemented_FPop */ 2070 case (3 << 14): /* unimplemented_FPop */
2071 ret = do_mathemu(regs, f); 2071 ret = do_mathemu(regs, f, false);
2072 break; 2072 break;
2073 } 2073 }
2074 if (ret) 2074 if (ret)
@@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs)
2308 } else { 2308 } else {
2309 struct fpustate *f = FPUSTATE; 2309 struct fpustate *f = FPUSTATE;
2310 2310
2311 /* XXX maybe verify XFSR bits like 2311 /* On UltraSPARC T2 and later, FPU insns which
2312 * XXX do_fpother() does? 2312 * are not implemented in HW signal an illegal
2313 * instruction trap and do not set the FP Trap
2314 * Trap in the %fsr to unimplemented_FPop.
2313 */ 2315 */
2314 if (do_mathemu(regs, f)) 2316 if (do_mathemu(regs, f, true))
2315 return; 2317 return;
2316 } 2318 }
2317 } 2319 }
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S
index 0e1605697b49..89c2c29f154b 100644
--- a/arch/sparc/kernel/vmlinux.lds.S
+++ b/arch/sparc/kernel/vmlinux.lds.S
@@ -107,6 +107,11 @@ SECTIONS
107 *(.sun4v_2insn_patch) 107 *(.sun4v_2insn_patch)
108 __sun4v_2insn_patch_end = .; 108 __sun4v_2insn_patch_end = .;
109 } 109 }
110 .leon_1insn_patch : {
111 __leon_1insn_patch = .;
112 *(.leon_1insn_patch)
113 __leon_1insn_patch_end = .;
114 }
110 .swapper_tsb_phys_patch : { 115 .swapper_tsb_phys_patch : {
111 __swapper_tsb_phys_patch = .; 116 __swapper_tsb_phys_patch = .;
112 *(.swapper_tsb_phys_patch) 117 *(.swapper_tsb_phys_patch)
diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S
index 4c2de3cf309b..28a7bc69f82b 100644
--- a/arch/sparc/kernel/wof.S
+++ b/arch/sparc/kernel/wof.S
@@ -332,24 +332,30 @@ spwin_srmmu_stackchk:
332 mov AC_M_SFSR, %glob_tmp 332 mov AC_M_SFSR, %glob_tmp
333 333
334 /* Clear the fault status and turn on the no_fault bit. */ 334 /* Clear the fault status and turn on the no_fault bit. */
335 lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR 335LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR
336SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR
336 337
337 lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control 338LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control
339SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control
338 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit 340 or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit
339 sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it 341LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it
342SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it
340 343
341 /* Dump the registers and cross fingers. */ 344 /* Dump the registers and cross fingers. */
342 STORE_WINDOW(sp) 345 STORE_WINDOW(sp)
343 346
344 /* Clear the no_fault bit and check the status. */ 347 /* Clear the no_fault bit and check the status. */
345 andn %glob_tmp, 0x2, %glob_tmp 348 andn %glob_tmp, 0x2, %glob_tmp
346 sta %glob_tmp, [%g0] ASI_M_MMUREGS 349LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS)
350SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS)
347 351
348 mov AC_M_SFAR, %glob_tmp 352 mov AC_M_SFAR, %glob_tmp
349 lda [%glob_tmp] ASI_M_MMUREGS, %g0 353LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0)
354SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0)
350 355
351 mov AC_M_SFSR, %glob_tmp 356 mov AC_M_SFSR, %glob_tmp
352 lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp 357LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)
358SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp)
353 andcc %glob_tmp, 0x2, %g0 ! did we fault? 359 andcc %glob_tmp, 0x2, %g0 ! did we fault?
354 be,a spwin_finish_up + 0x4 ! cool beans, success 360 be,a spwin_finish_up + 0x4 ! cool beans, success
355 restore %g0, %g0, %g0 361 restore %g0, %g0, %g0
diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S
index 9fde91a249e0..2c21cc59683e 100644
--- a/arch/sparc/kernel/wuf.S
+++ b/arch/sparc/kernel/wuf.S
@@ -254,16 +254,19 @@ srmmu_fwin_stackchk:
254 mov AC_M_SFSR, %l4 254 mov AC_M_SFSR, %l4
255 cmp %l5, %sp 255 cmp %l5, %sp
256 bleu fwin_user_stack_is_bolixed 256 bleu fwin_user_stack_is_bolixed
257 lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status 257LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status
258SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status
258 259
259 /* The technique is, turn off faults on this processor, 260 /* The technique is, turn off faults on this processor,
260 * just let the load rip, then check the sfsr to see if 261 * just let the load rip, then check the sfsr to see if
261 * a fault did occur. Then we turn on fault traps again 262 * a fault did occur. Then we turn on fault traps again
262 * and branch conditionally based upon what happened. 263 * and branch conditionally based upon what happened.
263 */ 264 */
264 lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg 265LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg
266SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg
265 or %l5, 0x2, %l5 ! turn on no-fault bit 267 or %l5, 0x2, %l5 ! turn on no-fault bit
266 sta %l5, [%g0] ASI_M_MMUREGS ! store it 268LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it
269SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it
267 270
268 /* Cross fingers and go for it. */ 271 /* Cross fingers and go for it. */
269 LOAD_WINDOW(sp) 272 LOAD_WINDOW(sp)
@@ -275,18 +278,22 @@ srmmu_fwin_stackchk:
275 278
276 /* LOCATION: Window 'T' */ 279 /* LOCATION: Window 'T' */
277 280
278 lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again 281LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
279 andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit 282SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again
280 sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it 283 andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit
284LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it
285SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it
281 286
282 mov AC_M_SFAR, %twin_tmp2 287 mov AC_M_SFAR, %twin_tmp2
283 lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address 288LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address
289SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address
284 290
285 mov AC_M_SFSR, %twin_tmp2 291 mov AC_M_SFSR, %twin_tmp2
286 lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status 292LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status
287 andcc %twin_tmp2, 0x2, %g0 ! did fault occur? 293SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status
294 andcc %twin_tmp2, 0x2, %g0 ! did fault occur?
288 295
289 bne 1f ! yep, cleanup 296 bne 1f ! yep, cleanup
290 nop 297 nop
291 298
292 wr %t_psr, 0x0, %psr 299 wr %t_psr, 0x0, %psr