diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-01-04 16:03:48 +0000 |
commit | 78c388aed2b7184182c08428db1de6c872d815f5 (patch) | |
tree | 4b2003b1b4ceb241a17faa995da8dd1004bb8e45 /arch/sparc64/kernel/traps.c | |
parent | eb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (diff) |
Merge with Linux 2.1.131 and more MIPS goodies.
(Did I mention that CVS is buggy ...)
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r-- | arch/sparc64/kernel/traps.c | 111 |
1 files changed, 100 insertions, 11 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index e1d652841..cb5180fff 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1,4 +1,4 @@ -/* $Id: traps.c,v 1.51 1998/06/12 14:54:20 jj Exp $ +/* $Id: traps.c,v 1.55 1998/10/11 06:58:22 davem Exp $ * arch/sparc64/kernel/traps.c * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -178,6 +178,79 @@ unsigned long syscall_trace_exit(unsigned long retval, struct pt_regs *regs) } #endif /* SYSCALL_TRACING */ +#if 0 +void rtrap_check(struct pt_regs *regs) +{ + register unsigned long pgd_phys asm("o1"); + register unsigned long pgd_cache asm("o2"); + register unsigned long g1_or_g3 asm("o3"); + register unsigned long g2 asm("o4"); + unsigned long ctx; + +#if 0 + do { + unsigned long test; + __asm__ __volatile__("rdpr %%pstate, %0" + : "=r" (test)); + if((test & PSTATE_MG) != 0 || + (test & PSTATE_IE) == 0) { + printk("rtrap_check: Bogus pstate[%016lx]\n", test); + return; + } + } while(0); +#endif + + __asm__ __volatile__(" + rdpr %%pstate, %%o5 + wrpr %%o5, %4, %%pstate + or %%g1, %%g3, %2 + mov %%g2, %3 + mov %%g7, %0 + mov %5, %1 + ldxa [%1] %6, %1 + wrpr %%o5, 0x0, %%pstate" + : "=r" (pgd_phys), "=r" (pgd_cache), + "=r" (g1_or_g3), "=r" (g2) + : "i" (PSTATE_IE | PSTATE_MG), "i" (TSB_REG), + "i" (ASI_DMMU) + : "o5"); + + ctx = spitfire_get_secondary_context(); + + if((pgd_phys != __pa(current->mm->pgd)) || + ((pgd_cache != 0) && + (pgd_cache != pgd_val(current->mm->pgd[0]))) || + (g1_or_g3 != (0xfffffffe00000000UL | 0x0000000000000018UL)) || +#define KERN_HIGHBITS ((_PAGE_VALID | _PAGE_SZ4MB) ^ 0xfffff80000000000) +#define KERN_LOWBITS (_PAGE_CP | _PAGE_CV | _PAGE_P | _PAGE_W) + (g2 != (KERN_HIGHBITS | KERN_LOWBITS)) || +#undef KERN_HIGHBITS +#undef KERN_LOWBITS + ((ctx != (current->mm->context & 0x3ff)) || + (ctx == 0) || + (current->tss.ctx != ctx))) { + printk("SHIT[%s:%d]: " + "(PP[%016lx] CACH[%016lx] CTX[%x] g1g3[%016lx] g2[%016lx]) ", + current->comm, current->pid, + pgd_phys, pgd_cache, ctx, g1_or_g3, g2); + printk("SHIT[%s:%d]: " + "[PP[%016lx] CACH[%016lx] CTX[%x:%x]] PC[%016lx:%016lx]\n", + current->comm, current->pid, + __pa(current->mm->pgd), + pgd_val(current->mm->pgd[0]), + current->mm->context & 0x3ff, + current->tss.ctx, + regs->tpc, regs->tnpc); + show_regs(regs); +#if 1 + __sti(); + while(1) + barrier(); +#endif + } +} +#endif + void bad_trap (struct pt_regs *regs, long lvl) { lock_kernel (); @@ -205,7 +278,20 @@ void bad_trap_tl1 (struct pt_regs *regs, long lvl) unlock_kernel(); } -void data_access_exception (struct pt_regs *regs) +void instruction_access_exception (struct pt_regs *regs, + unsigned long sfsr, unsigned long sfar) +{ + lock_kernel(); +#if 1 + printk("instruction_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n", + sfsr, sfar); +#endif + die_if_kernel("Iax", regs); + unlock_kernel(); +} + +void data_access_exception (struct pt_regs *regs, + unsigned long sfsr, unsigned long sfar) { if (regs->tstate & TSTATE_PRIV) { /* Test if this comes from uaccess places. */ @@ -224,7 +310,17 @@ void data_access_exception (struct pt_regs *regs) regs->u_regs[UREG_G2] = g2; return; } + /* Shit... */ +#if 1 + printk("data_access_exception: Shit SFSR[%016lx] SFAR[%016lx], going.\n", + sfsr, sfar); +#endif + die_if_kernel("Dax", regs); } +#if 0 + else + rtrap_check(regs); +#endif lock_kernel(); force_sig(SIGSEGV, current); unlock_kernel(); @@ -286,7 +382,7 @@ void do_dae(struct pt_regs *regs) unlock_kernel(); } -void instruction_access_exception (struct pt_regs *regs) +void do_iae(struct pt_regs *regs) { clean_and_reenable_l1_caches(); @@ -295,13 +391,6 @@ void instruction_access_exception (struct pt_regs *regs) unlock_kernel(); } -void do_iae(struct pt_regs *regs) -{ - lock_kernel(); - force_sig(SIGSEGV, current); - unlock_kernel(); -} - void do_fpe_common(struct pt_regs *regs) { if(regs->tstate & TSTATE_PRIV) { @@ -572,7 +661,7 @@ void cache_flush_trap(struct pt_regs *regs) #ifndef __SMP__ unsigned node = linux_cpus[get_cpuid()].prom_node; #else -#error SMP not supported on sparc64 yet +#error cache_flush_trap not supported on sparc64/SMP yet #endif #if 0 |