--- traps.c.orig 2002-09-07 21:30:15.000000000 -0400 +++ traps.c.new 2002-09-07 21:30:05.000000000 -0400 @@ -425,11 +425,11 @@ /* - * This routine handles page faults. It determines the address, + * This routine handles various exception codes. It determines the address, * and the problem, and then passes it off to one of the appropriate * routines. */ -void parisc_terminate(char *msg, struct pt_regs *regs, int code, unsigned long offset) +void parisc_handle_code(char *msg, struct pt_regs *regs, int code, unsigned long offset) { static spinlock_t terminate_lock = SPIN_LOCK_UNLOCKED; @@ -444,8 +444,17 @@ if (!console_drivers) pdc_console_restart(); - if (code == 1) - transfer_pim_to_trap_frame(regs); + + /* Not all switch paths will gutter the processor... */ + switch(code){ + + case 1: + transfer_pim_to_trap_frame(regs); + break; + + default: + /* Fall through */ + } show_stack(regs); @@ -461,6 +470,7 @@ * system will shut down immediately right here. */ pdc_soft_power_button(0); + /* Gutter the processor... */ for(;;) ; } @@ -487,7 +497,7 @@ case 1: /* High-priority machine check (HPMC) */ - parisc_terminate("High Priority Machine Check (HPMC)", + parisc_handle_code("High Priority Machine Check (HPMC)", regs, code, 0); /* NOT REACHED */ @@ -554,6 +564,7 @@ die_if_kernel("Privileged register usage", regs, code); si.si_code = ILL_PRVREG; + /* Fall thru */ give_sigill: si.si_signo = SIGILL; si.si_errno = 0; @@ -568,6 +579,20 @@ si.si_addr = (void *) regs->iaoq[0]; force_sig_info(SIGFPE, &si, current); return; + + case 13: + /* Conditional Trap */ + /* The condition succees in an instruction which traps + * on condition + */ + si.si_signo = SIGFPE; + /* Set to zero, and let the userspace app figure it out from + * the insn pointed to by si_addr + */ + si.si_code = 0; + si.si_addr = (void *) regs->iaoq[0]; + force_sig_info(SIGFPE, &si, current); + return; case 14: /* Assist Exception Trap, i.e. floating point exception. */ @@ -575,11 +600,24 @@ handle_fpe(regs); return; + case 15: + /* Data TLB miss fault/Data page fault */ + /* Fall thru */ + case 16: + /* Non-access instruction TLB miss fault */ + /* The instruction TLB entry needed for the target address of the FIC + * is absent, and hardware can't find it, so we get to cleanup + */ + /* Fall thru */ case 17: /* Non-access data TLB miss fault/Non-access data page fault */ /* TODO: Still need to add slow path emulation code here */ + /* TODO: Understand what is meant by the TODO listed + * above this one. (Carlos - Sep 7, 2002) */ + fault_address = regs->ior; - parisc_terminate("Non access data tlb fault!",regs,code,fault_address); + fault_space = regs->isr; + break; case 18: /* PCXS only -- later cpu's split this into types 26,27 & 28 */ @@ -589,9 +627,8 @@ return; } /* Fall Through */ - - case 15: /* Data TLB miss fault/Data page fault */ - case 26: /* PCXL: Data memory access rights trap */ + case 26: + /* PCXL: Data memory access rights trap */ fault_address = regs->ior; fault_space = regs->isr; break; @@ -621,6 +658,11 @@ pt_regs_to_ssp(regs, &ssp); kgdb_trap(I_TAKEN_BR, &ssp, 1); ssp_to_pt_regs(&ssp, regs); + + /* FIXME: Should this break without setting fault_address + * and fault_space? They are required for the dump later on. + * (Carlos - Sep 7, 2002) */ + break; #endif /* CONFIG_KWDB */ @@ -656,7 +698,6 @@ up_read(¤t->mm->mmap_sem); } /* Fall Through */ - case 27: /* Data memory protection ID trap */ die_if_kernel("Protection id trap", regs, code); @@ -690,7 +731,7 @@ force_sig_info(SIGBUS, &si, current); return; } - parisc_terminate("Unexpected interruption", regs, code, 0); + parisc_handle_code("Unexpected interruption", regs, code, 0); /* NOT REACHED */ } @@ -719,7 +760,8 @@ */ if (fault_space == 0) - parisc_terminate("Kernel Fault", regs, code, fault_address); + parisc_handle_code("Kernel Fault", regs, code, fault_address); + /* NOT REACHED */ } #ifdef CONFIG_KWDB