summaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/traps.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-05-07 02:55:41 +0000
commitdcec8a13bf565e47942a1751a9cec21bec5648fe (patch)
tree548b69625b18cc2e88c3e68d0923be546c9ebb03 /arch/sparc64/kernel/traps.c
parent2e0f55e79c49509b7ff70ff1a10e1e9e90a3dfd4 (diff)
o Merge with Linux 2.1.99.
o Fix ancient bug in the ELF loader making ldd crash. o Fix ancient bug in the keyboard code for SGI, SNI and Jazz.
Diffstat (limited to 'arch/sparc64/kernel/traps.c')
-rw-r--r--arch/sparc64/kernel/traps.c103
1 files changed, 53 insertions, 50 deletions
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c
index 6e1d30990..b255c7623 100644
--- a/arch/sparc64/kernel/traps.c
+++ b/arch/sparc64/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.44 1998/01/09 16:39:35 jj Exp $
+/* $Id: traps.c,v 1.49 1998/04/06 16:09:38 jj Exp $
* arch/sparc64/kernel/traps.c
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -191,7 +191,7 @@ void bad_trap (struct pt_regs *regs, long lvl)
die_if_kernel ("Kernel bad trap", regs);
current->tss.sig_desc = SUBSIG_BADTRAP(lvl - 0x100);
current->tss.sig_address = regs->tpc;
- send_sig(SIGILL, current, 1);
+ force_sig(SIGILL, current);
unlock_kernel ();
}
@@ -225,7 +225,9 @@ void data_access_exception (struct pt_regs *regs)
return;
}
}
- send_sig(SIGSEGV, current, 1);
+ lock_kernel();
+ force_sig(SIGSEGV, current);
+ unlock_kernel();
}
#ifdef CONFIG_PCI
@@ -235,16 +237,35 @@ extern volatile int pci_poke_in_progress;
extern volatile int pci_poke_faulted;
#endif
+/* When access exceptions happen, we must do this. */
+static __inline__ void clean_and_reenable_l1_caches(void)
+{
+ unsigned long va;
+
+ /* Clean 'em. */
+ for(va = 0; va < (PAGE_SIZE << 1); va += 32) {
+ spitfire_put_icache_tag(va, 0x0);
+ spitfire_put_dcache_tag(va, 0x0);
+ }
+
+ /* Re-enable. */
+ __asm__ __volatile__("flush %%g6\n\t"
+ "membar #Sync\n\t"
+ "stxa %0, [%%g0] %1\n\t"
+ "membar #Sync"
+ : /* no outputs */
+ : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
+ LSU_CONTROL_IM | LSU_CONTROL_DM),
+ "i" (ASI_LSU_CONTROL)
+ : "memory");
+}
+
void do_dae(struct pt_regs *regs)
{
#ifdef CONFIG_PCI
-#ifdef DEBUG_PCI_POKES
- prom_printf(" (POKE ");
-#endif
if(pci_poke_in_progress) {
- unsigned long va;
#ifdef DEBUG_PCI_POKES
- prom_printf("tpc[%016lx] tnpc[%016lx] ",
+ prom_printf(" (POKE tpc[%016lx] tnpc[%016lx] ",
regs->tpc, regs->tnpc);
#endif
pci_poke_faulted = 1;
@@ -255,39 +276,30 @@ void do_dae(struct pt_regs *regs)
prom_printf("PCI) ");
/* prom_halt(); */
#endif
- /* Re-enable I/D caches, Ultra turned them off. */
- for(va = 0; va < (PAGE_SIZE << 1); va += 32) {
- spitfire_put_icache_tag(va, 0x0);
- spitfire_put_dcache_tag(va, 0x0);
- }
- __asm__ __volatile__("flush %%g6\n\t"
- "membar #Sync\n\t"
- "stxa %0, [%%g0] %1\n\t"
- "membar #Sync"
- : /* no outputs */
- : "r" (LSU_CONTROL_IC | LSU_CONTROL_DC |
- LSU_CONTROL_IM | LSU_CONTROL_DM),
- "i" (ASI_LSU_CONTROL)
- : "memory");
+ clean_and_reenable_l1_caches();
return;
}
-#ifdef DEBUG_PCI_POKES
- prom_printf("USER) ");
- prom_printf("tpc[%016lx] tnpc[%016lx]\n");
- prom_halt();
#endif
-#endif
- send_sig(SIGSEGV, current, 1);
+ clean_and_reenable_l1_caches();
+ lock_kernel();
+ force_sig(SIGSEGV, current);
+ unlock_kernel();
}
void instruction_access_exception (struct pt_regs *regs)
{
- send_sig(SIGSEGV, current, 1);
+ clean_and_reenable_l1_caches();
+
+ lock_kernel();
+ force_sig(SIGSEGV, current);
+ unlock_kernel();
}
void do_iae(struct pt_regs *regs)
{
- send_sig(SIGSEGV, current, 1);
+ lock_kernel();
+ force_sig(SIGSEGV, current);
+ unlock_kernel();
}
void do_fpe_common(struct pt_regs *regs)
@@ -312,11 +324,7 @@ void do_fpieee(struct pt_regs *regs)
do_fpe_common(regs);
}
-#ifdef CONFIG_MATHEMU_MODULE
-volatile int (*handle_mathemu)(struct pt_regs *, struct fpustate *) = NULL;
-#else
extern int do_mathemu(struct pt_regs *, struct fpustate *);
-#endif
void do_fpother(struct pt_regs *regs)
{
@@ -326,18 +334,7 @@ void do_fpother(struct pt_regs *regs)
switch ((f->fsr & 0x1c000)) {
case (2 << 14): /* unfinished_FPop */
case (3 << 14): /* unimplemented_FPop */
-#ifdef CONFIG_MATHEMU_MODULE
-#ifdef CONFIG_KMOD
- if (!handle_mathemu)
- request_module("math-emu");
-#endif
- if (handle_mathemu)
- ret = handle_mathemu(regs, f);
-#else
-#ifdef CONFIG_MATHEMU
ret = do_mathemu(regs, f);
-#endif
-#endif
break;
}
if (ret) return;
@@ -576,27 +573,33 @@ void cache_flush_trap(struct pt_regs *regs)
#else
#error SMP not supported on sparc64 yet
#endif
+
+#if 0
+/* Broken */
int size = prom_getintdefault(node, "ecache-size", 512*1024);
int i, j;
- unsigned long addr, page_nr;
+ unsigned long addr;
+ struct page *page, *end;
regs->tpc = regs->tnpc;
regs->tnpc = regs->tnpc + 4;
if (!suser()) return;
size >>= PAGE_SHIFT;
addr = PAGE_OFFSET - PAGE_SIZE;
+ page = mem_map - 1;
+ end = mem_map + max_mapnr;
for (i = 0; i < size; i++) {
do {
addr += PAGE_SIZE;
- page_nr = MAP_NR(addr);
- if (page_nr >= max_mapnr) {
+ page++;
+ if (page >= end)
return;
- }
- } while (!PageReserved (mem_map + page_nr));
+ } while (!PageReserved(page));
/* E-Cache line size is 64B. Let us pollute it :)) */
for (j = 0; j < PAGE_SIZE; j += 64)
__asm__ __volatile__ ("ldx [%0 + %1], %%g1" : : "r" (j), "r" (addr) : "g1");
}
+#endif
}
#endif