diff options
Diffstat (limited to 'arch/sparc/kernel')
25 files changed, 295 insertions, 297 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 obj-y += of_device_$(BITS).o obj-$(CONFIG_SPARC64) += prom_irqtrans.o -obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o -obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o +obj-$(CONFIG_SPARC32) += leon_kernel.o +obj-$(CONFIG_SPARC32) += leon_pmc.o obj-$(CONFIG_SPARC64) += reboot.o obj-$(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[] = { FPU(-1, NULL) } },{ - 4, + PSR_IMPL_TI, .cpu_info = { CPU(0, "Texas Instruments, Inc. - SuperSparc-(II)"), /* SparcClassic -- borned STP1010TAB-50*/ @@ -191,7 +191,7 @@ static const struct manufacturer_info __initconst manufacturer_info[] = { FPU(-1, NULL) } },{ - 0xF, /* Aeroflex Gaisler */ + PSR_IMPL_LEON, /* Aeroflex Gaisler */ .cpu_info = { CPU(3, "LEON"), CPU(-1, NULL) @@ -440,16 +440,16 @@ static int __init cpu_type_probe(void) int psr_impl, psr_vers, fpu_vers; int psr; - psr_impl = ((get_psr() >> 28) & 0xf); - psr_vers = ((get_psr() >> 24) & 0xf); + psr_impl = ((get_psr() >> PSR_IMPL_SHIFT) & PSR_IMPL_SHIFTED_MASK); + psr_vers = ((get_psr() >> PSR_VERS_SHIFT) & PSR_VERS_SHIFTED_MASK); psr = get_psr(); put_psr(psr | PSR_EF); -#ifdef CONFIG_SPARC_LEON - fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; -#else - fpu_vers = ((get_fsr() >> 17) & 0x7); -#endif + + if (psr_impl == PSR_IMPL_LEON) + fpu_vers = get_psr() & PSR_EF ? ((get_fsr() >> 17) & 0x7) : 7; + else + fpu_vers = ((get_fsr() >> 17) & 0x7); put_psr(psr); 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: /* FIXME */ 1: b,a 1b -#ifdef CONFIG_SPARC_LEON .globl smpleon_ipi .extern leon_ipi_interrupt /* SMP per-cpu IPI interrupts are handled specially. */ @@ -424,8 +423,6 @@ linux_trap_ipi15_leon: b ret_trap_lockless_ipi clr %l6 -#endif /* CONFIG_SPARC_LEON */ - #endif /* CONFIG_SMP */ /* This routine handles illegal instructions and privileged @@ -770,8 +767,11 @@ srmmu_fault: mov 0x400, %l5 mov 0x300, %l4 - lda [%l5] ASI_M_MMUREGS, %l6 ! read sfar first - lda [%l4] ASI_M_MMUREGS, %l5 ! read sfsr last +LEON_PI(lda [%l5] ASI_LEON_MMUREGS, %l6) ! read sfar first +SUN_PI_(lda [%l5] ASI_M_MMUREGS, %l6) ! read sfar first + +LEON_PI(lda [%l4] ASI_LEON_MMUREGS, %l5) ! read sfsr last +SUN_PI_(lda [%l4] ASI_M_MMUREGS, %l5) ! read sfsr last andn %l6, 0xfff, %l6 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: cmp %glob_tmp, %sp bleu,a 1f - lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control +LEON_PI( lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control +SUN_PI_( lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control trap_setup_user_stack_is_bolixed: /* From user/kernel into invalid window w/bad user @@ -249,18 +250,25 @@ trap_setup_user_stack_is_bolixed: 1: /* Clear the fault status and turn on the no_fault bit. */ or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit - sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp - sta %glob_tmp, [%g0] ASI_M_MMUREGS +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) + mov AC_M_SFAR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) + mov AC_M_SFSR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp ! save away status of winstore +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp)! save away status of winstore +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) ! save away status of winstore + andcc %glob_tmp, 0x2, %g0 ! did we fault? bne trap_setup_user_stack_is_bolixed ! failure 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 @@ * the cpu-type */ .align 4 -cputyp: - .word 1 - - .align 4 .globl cputypval cputypval: .asciz "sun4m" @@ -46,8 +42,8 @@ cputypvar: .align 4 -sun4c_notsup: - .asciz "Sparc-Linux sun4/sun4c support does no longer exist.\n\n" +notsup: + .asciz "Sparc-Linux sun4/sun4c or MMU-less not supported\n\n" .align 4 sun4e_notsup: @@ -123,7 +119,7 @@ current_pc: tst %o0 be no_sun4u_here mov %g4, %o7 /* Previous %o7. */ - + mov %o0, %l0 ! stash away romvec mov %o0, %g7 ! put it here too mov %o1, %l1 ! stash away debug_vec too @@ -132,7 +128,7 @@ current_pc: set current_pc, %g5 cmp %g3, %g5 be already_mapped - nop + nop /* %l6 will hold the offset we have to subtract * from absolute symbols in order to access areas @@ -192,9 +188,9 @@ copy_prom_done: bne not_a_sun4 nop -halt_sun4_or_sun4c: +halt_notsup: ld [%g7 + 0x68], %o1 - set sun4c_notsup, %o0 + set notsup, %o0 sub %o0, %l6, %o0 call %o1 nop @@ -202,18 +198,31 @@ halt_sun4_or_sun4c: nop not_a_sun4: + /* It looks like this is a machine we support. + * Now find out what MMU we are dealing with + * LEON - identified by the psr.impl field + * Viking - identified by the psr.impl field + * In all other cases a sun4m srmmu. + * We check that the MMU is enabled in all cases. + */ + + /* Check if this is a LEON CPU */ + rd %psr, %g3 + srl %g3, PSR_IMPL_SHIFT, %g3 + and %g3, PSR_IMPL_SHIFTED_MASK, %g3 + cmp %g3, PSR_IMPL_LEON + be leon_remap /* It is a LEON - jump */ + nop + + /* Sanity-check, is MMU enabled */ lda [%g0] ASI_M_MMUREGS, %g1 andcc %g1, 1, %g0 - be halt_sun4_or_sun4c + be halt_notsup nop -srmmu_remap: - /* First, check for a viking (TI) module. */ - set 0x40000000, %g2 - rd %psr, %g3 - and %g2, %g3, %g3 - subcc %g3, 0x0, %g0 - bz srmmu_nviking + /* Check for a viking (TI) module. */ + cmp %g3, PSR_IMPL_TI + bne srmmu_not_viking nop /* Figure out what kind of viking we are on. @@ -228,14 +237,14 @@ srmmu_remap: lda [%g0] ASI_M_MMUREGS, %g3 ! peek in the control reg and %g2, %g3, %g3 subcc %g3, 0x0, %g0 - bnz srmmu_nviking ! is in mbus mode + bnz srmmu_not_viking ! is in mbus mode nop - + rd %psr, %g3 ! DO NOT TOUCH %g3 andn %g3, PSR_ET, %g2 wr %g2, 0x0, %psr WRITE_PAUSE - + /* Get context table pointer, then convert to * a physical address, which is 36 bits. */ @@ -258,12 +267,12 @@ srmmu_remap: lda [%g4] ASI_M_BYPASS, %o1 ! This is a level 1 ptr srl %o1, 0x4, %o1 ! Clear low 4 bits sll %o1, 0x8, %o1 ! Make physical - + /* Ok, pull in the PTD. */ lda [%o1] ASI_M_BYPASS, %o2 ! This is the 0x0 16MB pgd /* Calculate to KERNBASE entry. */ - add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 + add %o1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %o3 /* Poke the entry into the calculated address. */ sta %o2, [%o3] ASI_M_BYPASS @@ -293,12 +302,12 @@ srmmu_remap: b go_to_highmem nop +srmmu_not_viking: /* This works on viking's in Mbus mode and all * other MBUS modules. It is virtually the same as * the above madness sans turning traps off and flipping * the AC bit. */ -srmmu_nviking: set AC_M_CTPR, %g1 lda [%g1] ASI_M_MMUREGS, %g1 ! get ctx table ptr sll %g1, 0x4, %g1 ! make physical addr @@ -313,6 +322,29 @@ srmmu_nviking: nop ! wheee.... +leon_remap: + /* Sanity-check, is MMU enabled */ + lda [%g0] ASI_LEON_MMUREGS, %g1 + andcc %g1, 1, %g0 + be halt_notsup + nop + + /* Same code as in the srmmu_not_viking case, + * with the LEON ASI for mmuregs + */ + set AC_M_CTPR, %g1 + lda [%g1] ASI_LEON_MMUREGS, %g1 ! get ctx table ptr + sll %g1, 0x4, %g1 ! make physical addr + lda [%g1] ASI_M_BYPASS, %g1 ! ptr to level 1 pg_table + srl %g1, 0x4, %g1 + sll %g1, 0x8, %g1 ! make phys addr for l1 tbl + + lda [%g1] ASI_M_BYPASS, %g2 ! get level1 entry for 0x0 + add %g1, KERNBASE >> (SRMMU_PGDIR_SHIFT - 2), %g3 + sta %g2, [%g3] ASI_M_BYPASS ! place at KERNBASE entry + b go_to_highmem + nop ! wheee.... + /* Now do a non-relative jump so that PC is in high-memory */ go_to_highmem: set execute_in_high_mem, %g1 @@ -336,8 +368,9 @@ execute_in_high_mem: sethi %hi(linux_dbvec), %g1 st %o1, [%g1 + %lo(linux_dbvec)] -/* Get the machine type via the mysterious romvec node operations. */ - + /* Get the machine type via the romvec + * getprops node operation + */ add %g7, 0x1c, %l1 ld [%l1], %l0 ld [%l0], %l0 @@ -356,9 +389,42 @@ execute_in_high_mem: ! to a buf where above string ! will get stored by the prom. -#ifdef CONFIG_SPARC_LEON - /* no cpu-type check is needed, it is a SPARC-LEON */ + /* Check value of "compatible" property. + * "value" => "model" + * leon => sparc_leon + * sun4m => sun4m + * sun4s => sun4m + * sun4d => sun4d + * sun4e => "no_sun4e_here" + * '*' => "no_sun4u_here" + * Check single letters only + */ + + set cputypval, %o2 + /* If cputypval[0] == 'l' (lower case letter L) this is leon */ + ldub [%o2], %l1 + cmp %l1, 'l' + be leon_init + nop + + /* Check cputypval[4] to find the sun model */ + ldub [%o2 + 0x4], %l1 + + cmp %l1, 'm' + be sun4m_init + cmp %l1, 's' + be sun4m_init + cmp %l1, 'd' + be sun4d_init + cmp %l1, 'e' + be no_sun4e_here ! Could be a sun4e. + nop + b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) + nop + +leon_init: + /* LEON CPU - set boot_cpu_id */ sethi %hi(boot_cpu_id), %g2 ! boot-cpu index #ifdef CONFIG_SMP @@ -376,26 +442,6 @@ execute_in_high_mem: ba continue_boot nop -#endif - -/* Check to cputype. We may be booted on a sun4u (64 bit box), - * and sun4d needs special treatment. - */ - - set cputypval, %o2 - ldub [%o2 + 0x4], %l1 - - cmp %l1, 'm' - be sun4m_init - cmp %l1, 's' - be sun4m_init - cmp %l1, 'd' - be sun4d_init - cmp %l1, 'e' - be no_sun4e_here ! Could be a sun4e. - nop - b no_sun4u_here ! AIEEE, a V9 sun4u... Get our BIG BROTHER kernel :)) - nop /* CPUID in bootbus can be found at PA 0xff0140000 */ #define SUN4D_BOOTBUS_CPUID 0xf0140000 @@ -431,9 +477,9 @@ sun4m_init: /* This sucks, apparently this makes Vikings call prom panic, will fix later */ 2: rd %psr, %o1 - srl %o1, 28, %o1 ! Get a type of the CPU + srl %o1, PSR_IMPL_SHIFT, %o1 ! Get a type of the CPU - subcc %o1, 4, %g0 ! TI: Viking or MicroSPARC + subcc %o1, PSR_IMPL_TI, %g0 ! TI: Viking or MicroSPARC be continue_boot nop @@ -459,10 +505,6 @@ continue_boot: /* Aieee, now set PC and nPC, enable traps, give ourselves a stack and it's * show-time! */ - - sethi %hi(cputyp), %o0 - st %g4, [%o0 + %lo(cputyp)] - /* Turn on Supervisor, EnableFloating, and all the PIL bits. * Also puts us in register window zero with traps off. */ @@ -480,7 +522,7 @@ continue_boot: set __bss_start , %o0 ! First address of BSS set _end , %o1 ! Last address of BSS add %o0, 0x1, %o0 -1: +1: stb %g0, [%o0] subcc %o0, %o1, %g0 bl 1b @@ -546,7 +588,7 @@ continue_boot: set dest, %g2; \ ld [%g5], %g4; \ st %g4, [%g2]; - + /* Patch for window spills... */ PATCH_INSN(spnwin_patch1_7win, spnwin_patch1) PATCH_INSN(spnwin_patch2_7win, spnwin_patch2) @@ -597,7 +639,7 @@ continue_boot: st %g4, [%g5 + 0x18] st %g4, [%g5 + 0x1c] -2: +2: sethi %hi(nwindows), %g4 st %g3, [%g4 + %lo(nwindows)] ! store final value sub %g3, 0x1, %g3 @@ -617,18 +659,12 @@ continue_boot: wr %g3, PSR_ET, %psr WRITE_PAUSE - /* First we call prom_init() to set up PROMLIB, then - * off to start_kernel(). - */ - + /* Call sparc32_start_kernel(struct linux_romvec *rp) */ sethi %hi(prom_vector_p), %g5 ld [%g5 + %lo(prom_vector_p)], %o0 - call prom_init + call sparc32_start_kernel nop - call start_kernel - nop - /* We should not get here. */ call halt_me nop @@ -659,7 +695,7 @@ sun4u_5: .asciz "write" .align 4 sun4u_6: - .asciz "\n\rOn sun4u you have to use UltraLinux (64bit) kernel\n\rand not a 32bit sun4[cdem] version\n\r\n\r" + .asciz "\n\rOn sun4u you have to use sparc64 kernel\n\rand not a sparc32 version\n\r\n\r" sun4u_6e: .align 4 sun4u_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; /* This function must make sure that caches and memory are coherent after DMA * On LEON systems without cache snooping it flushes the entire D-CACHE. */ -#ifndef CONFIG_SPARC_LEON static inline void dma_make_coherent(unsigned long pa, unsigned long len) { + if (sparc_cpu_model == sparc_leon) { + if (!sparc_leon3_snooping_enabled()) + leon_flush_dcache_all(); + } } -#else -static inline void dma_make_coherent(unsigned long pa, unsigned long len) -{ - if (!sparc_leon3_snooping_enabled()) - leon_flush_dcache_all(); -} -#endif static void __iomem *_sparc_ioremap(struct resource *res, u32 bus, u32 pa, int sz); static void __iomem *_sparc_alloc_io(unsigned int busno, unsigned long phys, @@ -427,9 +423,6 @@ arch_initcall(sparc_register_ioport); #endif /* CONFIG_SBUS */ -/* LEON reuses PCI DMA ops */ -#if defined(CONFIG_PCI) || defined(CONFIG_SPARC_LEON) - /* Allocate and map kernel buffer using consistent mode DMA for a device. * hwdev should be valid struct pci_dev pointer for PCI devices. */ @@ -657,14 +650,11 @@ struct dma_map_ops pci32_dma_ops = { }; EXPORT_SYMBOL(pci32_dma_ops); -#endif /* CONFIG_PCI || CONFIG_SPARC_LEON */ +/* leon re-uses pci32_dma_ops */ +struct dma_map_ops *leon_dma_ops = &pci32_dma_ops; +EXPORT_SYMBOL(leon_dma_ops); -#ifdef CONFIG_SPARC_LEON -struct dma_map_ops *dma_ops = &pci32_dma_ops; -#elif defined(CONFIG_SBUS) struct dma_map_ops *dma_ops = &sbus_dma_ops; -#endif - EXPORT_SYMBOL(dma_ops); 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) unsigned int cpu_irq; int err; -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON - struct tt_entry *trap_table; -#endif err = request_irq(irq, irq_handler, 0, "floppy", NULL); if (err) @@ -264,13 +261,18 @@ int sparc_floppy_request_irq(unsigned int irq, irq_handler_t irq_handler) table[SP_TRAP_IRQ1+(cpu_irq-1)].inst_four = SPARC_NOP; INSTANTIATE(sparc_ttable) -#if defined CONFIG_SMP && !defined CONFIG_SPARC_LEON - trap_table = &trapbase_cpu1; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu2; - INSTANTIATE(trap_table) - trap_table = &trapbase_cpu3; - INSTANTIATE(trap_table) + +#if defined CONFIG_SMP + if (sparc_cpu_model != sparc_leon) { + struct tt_entry *trap_table; + + trap_table = &trapbase_cpu1; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu2; + INSTANTIATE(trap_table) + trap_table = &trapbase_cpu3; + INSTANTIATE(trap_table) + } #endif #undef INSTANTIATE /* 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) #endif #ifdef CONFIG_SPARC32 +/* setup_32.c */ +void sparc32_start_kernel(struct linux_romvec *rp); + /* cpu.c */ extern void cpu_probe(void); 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 @@ #include <asm/smp.h> #include <asm/setup.h> +#include "kernel.h" #include "prom.h" #include "irq.h" 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 @@ #include <linux/pm.h> #include <asm/leon_amba.h> +#include <asm/cpu_type.h> #include <asm/leon.h> /* List of Systems that need fixup instructions around power-down instruction */ @@ -65,13 +66,15 @@ void pmc_leon_idle(void) /* Install LEON Power Down function */ static int __init leon_pmc_install(void) { - /* Assign power management IDLE handler */ - if (pmc_leon_need_fixup()) - pm_idle = pmc_leon_idle_fixup; - else - pm_idle = pmc_leon_idle; + if (sparc_cpu_model == sparc_leon) { + /* Assign power management IDLE handler */ + if (pmc_leon_need_fixup()) + pm_idle = pmc_leon_idle_fixup; + else + pm_idle = pmc_leon_idle; - printk(KERN_INFO "leon: power management initialized\n"); + printk(KERN_INFO "leon: power management initialized\n"); + } return 0; } 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 @@ #include "kernel.h" -#ifdef CONFIG_SPARC_LEON - #include "irq.h" extern ctxd_t *srmmu_ctx_table_phys; static int smp_processors_ready; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpumask_t smp_commenced_mask; -void __init leon_configure_cache_smp(void); +void __cpuinit leon_configure_cache_smp(void); static void leon_ipi_init(void); /* IRQ number of LEON IPIs */ @@ -123,7 +121,7 @@ void __cpuinit leon_callin(void) extern struct linux_prom_registers smp_penguin_ctable; -void __init leon_configure_cache_smp(void) +void __cpuinit leon_configure_cache_smp(void) { unsigned long cfg = sparc_leon3_get_dcachecfg(); int me = smp_processor_id(); @@ -507,5 +505,3 @@ void __init leon_init_smp(void) sparc32_ipi_ops = &leon_ipi_ops; } - -#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 *); struct task_struct *last_task_used_math = NULL; struct thread_info *current_set[NR_CPUS]; -#ifndef CONFIG_SMP - /* * the idle loop on a Sparc... ;) */ void cpu_idle(void) { - /* endless idle loop with no priority at all */ - for (;;) { - if (pm_idle) { - while (!need_resched()) - (*pm_idle)(); - } else { - while (!need_resched()) - cpu_relax(); - } - schedule_preempt_disabled(); - } -} - -#else + set_thread_flag(TIF_POLLING_NRFLAG); -/* This is being executed in task 0 'user space'. */ -void cpu_idle(void) -{ - set_thread_flag(TIF_POLLING_NRFLAG); /* endless idle loop with no priority at all */ - while(1) { -#ifdef CONFIG_SPARC_LEON - if (pm_idle) { - while (!need_resched()) + for (;;) { + while (!need_resched()) { + if (pm_idle) (*pm_idle)(); - } else -#endif - { - while (!need_resched()) + else cpu_relax(); } schedule_preempt_disabled(); } } -#endif - /* XXX cli/sti -> local_irq_xxx here, check this works once SMP is fixed. */ void machine_halt(void) { 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 @@ #include <linux/of_pdt.h> #include <asm/prom.h> #include <asm/oplib.h> -#include <asm/leon.h> #include "prom.h" 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: cmp %g1, %fp bleu ret_trap_user_stack_is_bolixed mov AC_M_SFSR, %g1 - lda [%g1] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g0) - lda [%g0] ASI_M_MMUREGS, %g1 +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %g1) +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %g1) or %g1, 0x2, %g1 - sta %g1, [%g0] ASI_M_MMUREGS +LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) restore %g0, %g0, %g0 @@ -244,13 +247,16 @@ srmmu_rett_stackchk: save %g0, %g0, %g0 andn %g1, 0x2, %g1 - sta %g1, [%g0] ASI_M_MMUREGS +LEON_PI(sta %g1, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %g1, [%g0] ASI_M_MMUREGS) mov AC_M_SFAR, %g2 - lda [%g2] ASI_M_MMUREGS, %g2 +LEON_PI(lda [%g2] ASI_LEON_MMUREGS, %g2) +SUN_PI_(lda [%g2] ASI_M_MMUREGS, %g2) mov AC_M_SFSR, %g1 - lda [%g1] ASI_M_MMUREGS, %g1 +LEON_PI(lda [%g1] ASI_LEON_MMUREGS, %g1) +SUN_PI_(lda [%g1] ASI_M_MMUREGS, %g1) andcc %g1, 0x2, %g0 be ret_trap_userwins_ok 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 @@ #include <linux/cpu.h> #include <linux/kdebug.h> #include <linux/export.h> +#include <linux/start_kernel.h> #include <asm/io.h> #include <asm/processor.h> @@ -45,6 +46,7 @@ #include <asm/cpudata.h> #include <asm/setup.h> #include <asm/cacheflush.h> +#include <asm/sections.h> #include "kernel.h" @@ -237,28 +239,42 @@ static void __init per_cpu_patch(void) } } +struct leon_1insn_patch_entry { + unsigned int addr; + unsigned int insn; +}; + enum sparc_cpu sparc_cpu_model; EXPORT_SYMBOL(sparc_cpu_model); -struct tt_entry *sparc_ttable; +static __init void leon_patch(void) +{ + struct leon_1insn_patch_entry *start = (void *)__leon_1insn_patch; + struct leon_1insn_patch_entry *end = (void *)__leon_1insn_patch_end; -struct pt_regs fake_swapper_regs; + /* Default instruction is leon - no patching */ + if (sparc_cpu_model == sparc_leon) + return; -void __init setup_arch(char **cmdline_p) -{ - int i; - unsigned long highest_paddr; + while (start < end) { + unsigned long addr = start->addr; - sparc_ttable = (struct tt_entry *) &trapbase; + *(unsigned int *)(addr) = start->insn; + flushi(addr); - /* Initialize PROM console and command line. */ - *cmdline_p = prom_getbootargs(); - strcpy(boot_command_line, *cmdline_p); - parse_early_param(); + start++; + } +} - boot_flags_init(*cmdline_p); +struct tt_entry *sparc_ttable; +struct pt_regs fake_swapper_regs; - register_console(&prom_early_console); +/* Called from head_32.S - before we have setup anything + * in the kernel. Be very careful with what you do here. + */ +void __init sparc32_start_kernel(struct linux_romvec *rp) +{ + prom_init(rp); /* Set sparc_cpu_model */ sparc_cpu_model = sun_unknown; @@ -275,6 +291,26 @@ void __init setup_arch(char **cmdline_p) if (!strncmp(&cputypval[0], "leon" , 4)) sparc_cpu_model = sparc_leon; + leon_patch(); + start_kernel(); +} + +void __init setup_arch(char **cmdline_p) +{ + int i; + unsigned long highest_paddr; + + sparc_ttable = (struct tt_entry *) &trapbase; + + /* Initialize PROM console and command line. */ + *cmdline_p = prom_getbootargs(); + strcpy(boot_command_line, *cmdline_p); + parse_early_param(); + + boot_flags_init(*cmdline_p); + + register_console(&prom_early_console); + printk("ARCH: "); switch(sparc_cpu_model) { case sun4m: diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c index bb1513e45f1a..a53e0a5fd3a3 100644 --- a/arch/sparc/kernel/signal32.c +++ b/arch/sparc/kernel/signal32.c @@ -32,8 +32,6 @@ #include "sigutil.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* This magic should be in g_upper[0] for all upper parts * to be valid. */ @@ -274,7 +272,6 @@ void do_sigreturn32(struct pt_regs *regs) case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32); case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32); } - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); return; @@ -376,7 +373,6 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32); case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32); } - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); return; segv: @@ -775,7 +771,7 @@ sigsegv: return -EFAULT; } -static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, +static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { @@ -787,12 +783,9 @@ static inline int handle_signal32(unsigned long signr, struct k_sigaction *ka, err = setup_frame32(ka, regs, signr, oldset); if (err) - return err; - - block_sigmask(ka, signr); - tracehook_signal_handler(signr, info, ka, regs, 0); + return; - return 0; + signal_delivered(signr, info, ka, regs, 0); } static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, @@ -841,14 +834,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs) if (signr > 0) { if (restart_syscall) syscall_restart32(orig_i0, regs, &ka.sa); - if (handle_signal32(signr, &ka, &info, oldset, regs) == 0) { - /* A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - } + handle_signal32(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && @@ -872,10 +858,7 @@ void do_signal32(sigset_t *oldset, struct pt_regs * regs) /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - set_current_blocked(¤t->saved_sigmask); - } + restore_saved_sigmask(); } struct sigstack32 { diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c index 2b7e849f7c65..68f9c8650af4 100644 --- a/arch/sparc/kernel/signal_32.c +++ b/arch/sparc/kernel/signal_32.c @@ -29,8 +29,6 @@ #include "sigutil.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - extern void fpsave(unsigned long *fpregs, unsigned long *fsr, void *fpqueue, unsigned long *fpqdepth); extern void fpload(unsigned long *fpregs, unsigned long *fsr); @@ -130,7 +128,6 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) if (err) goto segv_and_exit; - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); return; @@ -197,7 +194,6 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) goto segv; } - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); return; segv: @@ -449,10 +445,11 @@ sigsegv: return -EFAULT; } -static inline int +static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, - siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) + siginfo_t *info, struct pt_regs *regs) { + sigset_t *oldset = sigmask_to_save(); int err; if (ka->sa.sa_flags & SA_SIGINFO) @@ -461,12 +458,9 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, err = setup_frame(ka, regs, signr, oldset); if (err) - return err; - - block_sigmask(ka, signr); - tracehook_signal_handler(signr, info, ka, regs, 0); + return; - return 0; + signal_delivered(signr, info, ka, regs, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -498,7 +492,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; int restart_syscall; - sigset_t *oldset; siginfo_t info; int signr; @@ -523,11 +516,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) regs->u_regs[UREG_G6] = orig_i0; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - signr = get_signal_to_deliver(&info, &ka, regs, NULL); /* If the debugger messes with the program counter, it clears @@ -544,15 +532,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { - /* a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag. - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - } + handle_signal(signr, &ka, &info, regs); return; } if (restart_syscall && @@ -576,22 +556,17 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) /* if there's no signal to deliver, we just put the saved sigmask * back */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - set_current_blocked(¤t->saved_sigmask); - } + restore_saved_sigmask(); } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) { - if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) + if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs, orig_i0); if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c index eafaab486b2d..867de2f8189c 100644 --- a/arch/sparc/kernel/signal_64.c +++ b/arch/sparc/kernel/signal_64.c @@ -38,8 +38,6 @@ #include "systbls.h" #include "sigutil.h" -#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) - /* {set, get}context() needed for 64-bit SparcLinux userland. */ asmlinkage void sparc64_set_context(struct pt_regs *regs) { @@ -71,7 +69,6 @@ asmlinkage void sparc64_set_context(struct pt_regs *regs) if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t))) goto do_sigsegv; } - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); } if (test_thread_flag(TIF_32BIT)) { @@ -315,7 +312,6 @@ void do_rt_sigreturn(struct pt_regs *regs) /* Prevent syscall restart. */ pt_regs_clear_syscall(regs); - sigdelsetmask(&set, ~_BLOCKABLE); set_current_blocked(&set); return; segv: @@ -466,7 +462,7 @@ sigsegv: return -EFAULT; } -static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, +static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset, struct pt_regs *regs) { @@ -475,12 +471,9 @@ static inline int handle_signal(unsigned long signr, struct k_sigaction *ka, err = setup_rt_frame(ka, regs, signr, oldset, (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); if (err) - return err; - - block_sigmask(ka, signr); - tracehook_signal_handler(signr, info, ka, regs, 0); + return; - return 0; + signal_delivered(signr, info, ka, regs, 0); } static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, @@ -512,7 +505,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) { struct k_sigaction ka; int restart_syscall; - sigset_t *oldset; + sigset_t *oldset = sigmask_to_save(); siginfo_t info; int signr; @@ -538,11 +531,6 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) regs->u_regs[UREG_G6] = orig_i0; - if (current_thread_info()->status & TS_RESTORE_SIGMASK) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - #ifdef CONFIG_COMPAT if (test_thread_flag(TIF_32BIT)) { extern void do_signal32(sigset_t *, struct pt_regs *); @@ -563,14 +551,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) if (signr > 0) { if (restart_syscall) syscall_restart(orig_i0, regs, &ka.sa); - if (handle_signal(signr, &ka, &info, oldset, regs) == 0) { - /* A signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TS_RESTORE_SIGMASK flag. - */ - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - } + handle_signal(signr, &ka, &info, oldset, regs); return; } if (restart_syscall && @@ -594,10 +575,7 @@ static void do_signal(struct pt_regs *regs, unsigned long orig_i0) /* If there's no signal to deliver, we just put the saved sigmask * back */ - if (current_thread_info()->status & TS_RESTORE_SIGMASK) { - current_thread_info()->status &= ~TS_RESTORE_SIGMASK; - set_current_blocked(¤t->saved_sigmask); - } + restore_saved_sigmask(); } void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags) @@ -607,8 +585,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 3ee51f189a55..275f74fd6f6a 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c @@ -580,16 +580,9 @@ SYSCALL_DEFINE5(64_mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr) { - unsigned long ret = -EINVAL; - if (test_thread_flag(TIF_32BIT)) - goto out; - - down_write(¤t->mm->mmap_sem); - ret = do_mremap(addr, old_len, new_len, flags, new_addr); - up_write(¤t->mm->mmap_sem); -out: - return ret; + return -EINVAL; + return sys_mremap(addr, old_len, new_len, flags, new_addr); } /* we come to here via sys_nis_syscall so it can setup the regs argument */ 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: b,a smp_do_cpu_idle -#ifdef CONFIG_SPARC_LEON - __CPUINIT .align 4 .global leon_smp_cpu_startup, smp_penguin_ctable @@ -161,7 +159,7 @@ leon_smp_cpu_startup: ld [%g1+4],%g1 srl %g1,4,%g1 set 0x00000100,%g5 /* SRMMU_CTXTBL_PTR */ - sta %g1, [%g5] ASI_M_MMUREGS + sta %g1, [%g5] ASI_LEON_MMUREGS /* Set up a sane %psr -- PIL<0xf> S<0x1> PS<0x1> CWP<0x0> */ set (PSR_PIL | PSR_S | PSR_PS), %g1 @@ -207,5 +205,3 @@ leon_smp_cpu_startup: nop b,a smp_do_cpu_idle - -#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) do_fpe_common(regs); } -extern int do_mathemu(struct pt_regs *, struct fpustate *); +extern int do_mathemu(struct pt_regs *, struct fpustate *, bool); void do_fpother(struct pt_regs *regs) { @@ -2068,7 +2068,7 @@ void do_fpother(struct pt_regs *regs) switch ((current_thread_info()->xfsr[0] & 0x1c000)) { case (2 << 14): /* unfinished_FPop */ case (3 << 14): /* unimplemented_FPop */ - ret = do_mathemu(regs, f); + ret = do_mathemu(regs, f, false); break; } if (ret) @@ -2308,10 +2308,12 @@ void do_illegal_instruction(struct pt_regs *regs) } else { struct fpustate *f = FPUSTATE; - /* XXX maybe verify XFSR bits like - * XXX do_fpother() does? + /* On UltraSPARC T2 and later, FPU insns which + * are not implemented in HW signal an illegal + * instruction trap and do not set the FP Trap + * Trap in the %fsr to unimplemented_FPop. */ - if (do_mathemu(regs, f)) + if (do_mathemu(regs, f, true)) return; } } diff --git a/arch/sparc/kernel/vio.c b/arch/sparc/kernel/vio.c index 5cffdc55f075..3e244f31e56b 100644 --- a/arch/sparc/kernel/vio.c +++ b/arch/sparc/kernel/vio.c @@ -443,7 +443,7 @@ static int __init vio_init(void) root_vdev = vio_create_one(hp, root, NULL); err = -ENODEV; if (!root_vdev) { - printk(KERN_ERR "VIO: Coult not create root device.\n"); + printk(KERN_ERR "VIO: Could not create root device.\n"); goto out_release; } 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 *(.sun4v_2insn_patch) __sun4v_2insn_patch_end = .; } + .leon_1insn_patch : { + __leon_1insn_patch = .; + *(.leon_1insn_patch) + __leon_1insn_patch_end = .; + } .swapper_tsb_phys_patch : { __swapper_tsb_phys_patch = .; *(.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: mov AC_M_SFSR, %glob_tmp /* Clear the fault status and turn on the no_fault bit. */ - lda [%glob_tmp] ASI_M_MMUREGS, %g0 ! eat SFSR +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) ! eat SFSR +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) ! eat SFSR - lda [%g0] ASI_M_MMUREGS, %glob_tmp ! read MMU control +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %glob_tmp) ! read MMU control +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %glob_tmp) ! read MMU control or %glob_tmp, 0x2, %glob_tmp ! or in no_fault bit - sta %glob_tmp, [%g0] ASI_M_MMUREGS ! set it +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) ! set it +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) ! set it /* Dump the registers and cross fingers. */ STORE_WINDOW(sp) /* Clear the no_fault bit and check the status. */ andn %glob_tmp, 0x2, %glob_tmp - sta %glob_tmp, [%g0] ASI_M_MMUREGS +LEON_PI(sta %glob_tmp, [%g0] ASI_LEON_MMUREGS) +SUN_PI_(sta %glob_tmp, [%g0] ASI_M_MMUREGS) mov AC_M_SFAR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %g0 +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %g0) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %g0) mov AC_M_SFSR, %glob_tmp - lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp +LEON_PI(lda [%glob_tmp] ASI_LEON_MMUREGS, %glob_tmp) +SUN_PI_(lda [%glob_tmp] ASI_M_MMUREGS, %glob_tmp) andcc %glob_tmp, 0x2, %g0 ! did we fault? be,a spwin_finish_up + 0x4 ! cool beans, success 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: mov AC_M_SFSR, %l4 cmp %l5, %sp bleu fwin_user_stack_is_bolixed - lda [%l4] ASI_M_MMUREGS, %g0 ! clear fault status +LEON_PI( lda [%l4] ASI_LEON_MMUREGS, %g0) ! clear fault status +SUN_PI_( lda [%l4] ASI_M_MMUREGS, %g0) ! clear fault status /* The technique is, turn off faults on this processor, * just let the load rip, then check the sfsr to see if * a fault did occur. Then we turn on fault traps again * and branch conditionally based upon what happened. */ - lda [%g0] ASI_M_MMUREGS, %l5 ! read mmu-ctrl reg +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %l5) ! read mmu-ctrl reg +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %l5) ! read mmu-ctrl reg or %l5, 0x2, %l5 ! turn on no-fault bit - sta %l5, [%g0] ASI_M_MMUREGS ! store it +LEON_PI(sta %l5, [%g0] ASI_LEON_MMUREGS) ! store it +SUN_PI_(sta %l5, [%g0] ASI_M_MMUREGS) ! store it /* Cross fingers and go for it. */ LOAD_WINDOW(sp) @@ -275,18 +278,22 @@ srmmu_fwin_stackchk: /* LOCATION: Window 'T' */ - lda [%g0] ASI_M_MMUREGS, %twin_tmp1 ! load mmu-ctrl again - andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit - sta %twin_tmp1, [%g0] ASI_M_MMUREGS ! store it +LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %twin_tmp1) ! load mmu-ctrl again +SUN_PI_(lda [%g0] ASI_M_MMUREGS, %twin_tmp1) ! load mmu-ctrl again + andn %twin_tmp1, 0x2, %twin_tmp1 ! clear no-fault bit +LEON_PI(sta %twin_tmp1, [%g0] ASI_LEON_MMUREGS) ! store it +SUN_PI_(sta %twin_tmp1, [%g0] ASI_M_MMUREGS) ! store it mov AC_M_SFAR, %twin_tmp2 - lda [%twin_tmp2] ASI_M_MMUREGS, %g0 ! read fault address +LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %g0) ! read fault address +SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %g0) ! read fault address mov AC_M_SFSR, %twin_tmp2 - lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2 ! read fault status - andcc %twin_tmp2, 0x2, %g0 ! did fault occur? +LEON_PI(lda [%twin_tmp2] ASI_LEON_MMUREGS, %twin_tmp2) ! read fault status +SUN_PI_(lda [%twin_tmp2] ASI_M_MMUREGS, %twin_tmp2) ! read fault status + andcc %twin_tmp2, 0x2, %g0 ! did fault occur? - bne 1f ! yep, cleanup + bne 1f ! yep, cleanup nop wr %t_psr, 0x0, %psr |