diff options
author | Pixel <pixel@nobis-crew.org> | 2011-01-27 00:57:15 -0800 |
---|---|---|
committer | Pixel <pixel@nobis-crew.org> | 2011-01-27 00:57:15 -0800 |
commit | e1122d5200cec30e239b18278e2bb5c7ec97a72b (patch) | |
tree | 0c5956a7364239fc603e343bba34090864d288d1 /arch/arm | |
parent | 03638eaea432ac06456cded2cb743d20664689a7 (diff) |
(way) better fault handlers.
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/lpc17xx/handlers.c | 41 | ||||
-rw-r--r-- | arch/arm/lpc17xx/startup.s | 29 |
2 files changed, 48 insertions, 22 deletions
diff --git a/arch/arm/lpc17xx/handlers.c b/arch/arm/lpc17xx/handlers.c index 444c0c1..59a297b 100644 --- a/arch/arm/lpc17xx/handlers.c +++ b/arch/arm/lpc17xx/handlers.c @@ -2,24 +2,26 @@ #include "LPC17xx.h" enum FaultType { - NMI, HardFault, MemManage, BusFault, UsageFault, + NMI = 2, HardFault, MemManage, BusFault, UsageFault, }; -static inline void traceme() { - unsigned int i; - void * frame, * pc; - - i = 0; - frame = __builtin_frame_address(i); - pc = frame ? __builtin_return_address(i) : 0; - DBGOUT("lv%u; PC = %p, frame = %p\r\n", i, pc, frame); +struct fault_data_t { + uint32_t r0, r1, r2, r3, r12, lr, pc, xPSR, r4, r5, r6, r7, r8, r9, r10, r11; +}; + +static void print_fault_data(struct fault_data_t * fault_data) { + // These ones are saved naturally by the CPU + DBGOUT("pc: %p\r\n", fault_data->pc); + DBGOUT("sp = %p - lr = %p - r12 = %p -xPSR = %p\r\n", fault_data, fault_data->lr, fault_data->r12, fault_data->xPSR); + DBGOUT("r0 = %p - r1 = %p - r2 = %p - r3 = %p\r\n", fault_data->r0, fault_data->r1, fault_data->r2, fault_data->r3); + // These ones are saved by the ASM handler; not sure if they are proper + DBGOUT("r4 = %p - r5 = %p - r6 = %p - r7 = %p\r\n", fault_data->r4, fault_data->r5, fault_data->r6, fault_data->r7); + // Huh ? This read crashes the CPU... (cf previous comment) +// DBGOUT("r8 = %p - r9 = %p - r10 = %p - r11 = %p\r\n", fault_data->r8, fault_data->r9, fault_data->r10, fault_data->r11); } -static int general_Handler(enum FaultType fault) { - DBGOUT("***FAULT***\r\n"); - - traceme(); - +void general_C_handler(enum FaultType fault, struct fault_data_t * fault_data) { + DBGOUT("***FAULT***\r\nType: "); switch (fault) { case NMI: DBGOUT("NMI\r\n"); @@ -38,13 +40,8 @@ static int general_Handler(enum FaultType fault) { break; } - while(1); + print_fault_data(fault_data); - return 0; + DBGOUT("HALTING\r\n"); + while(1); } - -int NMI_Handler() { return general_Handler(NMI); } -int HardFault_Handler() { return general_Handler(HardFault); } -int MemManage_Handler() { return general_Handler(MemManage); } -int BusFault_Handler() { return general_Handler(BusFault); } -int UsageFault_Handler() { return general_Handler(UsageFault); } diff --git a/arch/arm/lpc17xx/startup.s b/arch/arm/lpc17xx/startup.s index a57954a..7537531 100644 --- a/arch/arm/lpc17xx/startup.s +++ b/arch/arm/lpc17xx/startup.s @@ -119,6 +119,35 @@ __cs3_interrupt_vector_cortex_m: .thumb +/* Fault handlers wrappers */ + + .section .privileged_code,"x",%progbits + .thumb_func + .type NMI_Handler, %function +NMI_Handler: + MOV R0, 2 + B general_handler + .type HardFault_Handler, %function +HardFault_Handler: + MOV R0, 3 + B general_handler + .type MemManage_Handler, %function +MemManage_Handler: + MOV R0, 4 + B general_handler + .type BusFault_Handler, %function +BusFault_Handler: + MOV R0, 5 + B general_handler + .type UsageFault_Handler, %function +UsageFault_Handler: + MOV R0, 6 + B general_handler + .type general_handler, %function +general_handler: + MOV R1, SP + PUSH {R4-R11} + B general_C_handler /* Reset Handler */ |