diff options
-rw-r--r-- | payloads/libpayload/arch/arm/exception.c | 12 | ||||
-rw-r--r-- | payloads/libpayload/include/arm/arch/cache.h | 48 | ||||
-rw-r--r-- | src/arch/arm/armv7/exception.c | 6 | ||||
-rw-r--r-- | src/arch/arm/include/armv7/arch/cache.h | 48 |
4 files changed, 114 insertions, 0 deletions
diff --git a/payloads/libpayload/arch/arm/exception.c b/payloads/libpayload/arch/arm/exception.c index d100937295..6f1796018b 100644 --- a/payloads/libpayload/arch/arm/exception.c +++ b/payloads/libpayload/arch/arm/exception.c @@ -90,6 +90,18 @@ void exception_dispatch(u32 idx) printf("%s Exception\n", names[idx]); print_regs(); + switch (idx) { + case EXC_PABORT: + printf("IFAR = %#.8x\n", read_ifar()); + printf("IFSR = %#.8x\n", read_ifsr()); + printf("AIFSR = %#.8x\n", read_aifsr()); + break; + case EXC_DABORT: + printf("DFAR = %#.8x\n", read_dfar()); + printf("DFSR = %#.8x\n", read_dfsr()); + printf("ADFSR = %#.8x\n", read_adfsr()); + break; + }; dump_stack(exception_state.regs[13], 512); halt(); } diff --git a/payloads/libpayload/include/arm/arch/cache.h b/payloads/libpayload/include/arm/arch/cache.h index 67f6fd4492..b258185b9b 100644 --- a/payloads/libpayload/include/arm/arch/cache.h +++ b/payloads/libpayload/include/arm/arch/cache.h @@ -268,6 +268,54 @@ static inline void write_sctlr(uint32_t val) isb(); } +/* read data fault address register (DFAR) */ +static inline uint32_t read_dfar(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r" (val)); + return val; +} + +/* read data fault status register (DFSR) */ +static inline uint32_t read_dfsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r" (val)); + return val; +} + +/* read instruction fault address register (IFAR) */ +static inline uint32_t read_ifar(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c6, c0, 2" : "=r" (val)); + return val; +} + +/* read instruction fault status register (IFSR) */ +static inline uint32_t read_ifsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c0, 1" : "=r" (val)); + return val; +} + +/* read auxiliary data fault status register (ADFSR) */ +static inline uint32_t read_adfsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c1, 0" : "=r" (val)); + return val; +} + +/* read auxiliary instruction fault status register (AIFSR) */ +static inline uint32_t read_aifsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c1, 1" : "=r" (val)); + return val; +} + /* * Cache maintenance API */ diff --git a/src/arch/arm/armv7/exception.c b/src/arch/arm/armv7/exception.c index eedd47d1d5..4fac0bcd3c 100644 --- a/src/arch/arm/armv7/exception.c +++ b/src/arch/arm/armv7/exception.c @@ -100,6 +100,9 @@ void exception_prefetch_abort(uint32_t *regs) printk(BIOS_ERR, "exception _prefetch_abort\n"); regs[15] -= 4; print_regs(regs); + printk(BIOS_ERR, "IFAR = %#.8x\n", read_ifar()); + printk(BIOS_ERR, "IFSR = %#.8x\n", read_ifsr()); + printk(BIOS_ERR, "AIFSR = %#.8x\n", read_aifsr()); dump_stack(regs[13], 512); die("exception"); } @@ -109,6 +112,9 @@ void exception_data_abort(uint32_t *regs) printk(BIOS_ERR, "exception _data_abort\n"); regs[15] -= 8; print_regs(regs); + printk(BIOS_ERR, "DFAR = %#.8x\n", read_dfar()); + printk(BIOS_ERR, "DFSR = %#.8x\n", read_dfsr()); + printk(BIOS_ERR, "ADFSR = %#.8x\n", read_adfsr()); dump_stack(regs[13], 512); die("exception"); } diff --git a/src/arch/arm/include/armv7/arch/cache.h b/src/arch/arm/include/armv7/arch/cache.h index f23dec1bbb..12df5c309f 100644 --- a/src/arch/arm/include/armv7/arch/cache.h +++ b/src/arch/arm/include/armv7/arch/cache.h @@ -295,6 +295,54 @@ static inline void write_sctlr(uint32_t val) isb(); } +/* read data fault address register (DFAR) */ +static inline uint32_t read_dfar(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r" (val)); + return val; +} + +/* read data fault status register (DFSR) */ +static inline uint32_t read_dfsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c0, 0" : "=r" (val)); + return val; +} + +/* read instruction fault address register (IFAR) */ +static inline uint32_t read_ifar(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c6, c0, 2" : "=r" (val)); + return val; +} + +/* read instruction fault status register (IFSR) */ +static inline uint32_t read_ifsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c0, 1" : "=r" (val)); + return val; +} + +/* read auxiliary data fault status register (ADFSR) */ +static inline uint32_t read_adfsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c1, 0" : "=r" (val)); + return val; +} + +/* read auxiliary instruction fault status register (AIFSR) */ +static inline uint32_t read_aifsr(void) +{ + uint32_t val; + asm volatile ("mrc p15, 0, %0, c5, c1, 1" : "=r" (val)); + return val; +} + /* * Cache maintenance API */ |