X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fppc%2Fkernel%2Ftraps.c;h=0d7eb748d709a54103a20a997bb7db43a91028b4;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=7870bb680563a81b57e9de188c89ddce330f021e;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 7870bb680..0d7eb748d 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -41,6 +41,7 @@ #ifdef CONFIG_PMAC_BACKLIGHT #include #endif +#include #ifdef CONFIG_XMON void (*debugger)(struct pt_regs *regs) = xmon; @@ -71,8 +72,7 @@ void (*debugger_fault_handler)(struct pt_regs *regs); * Trap & Exception support */ - -spinlock_t die_lock = SPIN_LOCK_UNLOCKED; +DEFINE_SPINLOCK(die_lock); void die(const char * str, struct pt_regs * fp, long err) { @@ -199,6 +199,15 @@ static inline int check_io_access(struct pt_regs *regs) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) #endif +/* + * This is "fall-back" implementation for configurations + * which don't provide platform-specific machine check info + */ +void __attribute__ ((weak)) +platform_machine_check(struct pt_regs *regs) +{ +} + void MachineCheckException(struct pt_regs *regs) { unsigned long reason = get_mc_reason(regs); @@ -323,6 +332,12 @@ void MachineCheckException(struct pt_regs *regs) } #endif /* CONFIG_4xx */ + /* + * Optional platform-provided routine to print out + * additional info, e.g. bus error registers. + */ + platform_machine_check(regs); + debugger(regs); die("machine check", regs, SIGBUS); } @@ -566,7 +581,7 @@ void ProgramCheckException(struct pt_regs *regs) void SingleStepException(struct pt_regs *regs) { - regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ + regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ if (debugger_sstep(regs)) return; _exception(SIGTRAP, regs, TRAP_TRACE, 0); @@ -647,22 +662,22 @@ void SoftwareEmulation(struct pt_regs *regs) } #endif /* CONFIG_8xx */ -#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) +#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) void DebugException(struct pt_regs *regs, unsigned long debug_status) { -#if 0 - if (debug_status & DBSR_TIE) { /* trap instruction*/ - if (!user_mode(regs) && debugger_bpt(regs)) - return; - _exception(SIGTRAP, regs, 0, 0); - - } -#endif if (debug_status & DBSR_IC) { /* instruction completion */ - if (!user_mode(regs) && debugger_sstep(regs)) - return; - current->thread.dbcr0 &= ~DBCR0_IC; + regs->msr &= ~MSR_DE; + if (user_mode(regs)) { + current->thread.dbcr0 &= ~DBCR0_IC; + } else { + /* Disable instruction completion */ + mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~DBCR0_IC); + /* Clear the instruction completion event */ + mtspr(SPRN_DBSR, DBSR_IC); + if (debugger_sstep(regs)) + return; + } _exception(SIGTRAP, regs, TRAP_TRACE, 0); } } @@ -726,6 +741,11 @@ void AltivecAssistException(struct pt_regs *regs) } #endif /* CONFIG_ALTIVEC */ +void PerformanceMonitorException(struct pt_regs *regs) +{ + perf_irq(regs); +} + #ifdef CONFIG_FSL_BOOKE void CacheLockingException(struct pt_regs *regs, unsigned long address, unsigned long error_code)