diff options
author | Antony Pavlov <antonynpavlov@gmail.com> | 2012-07-26 02:00:27 +0400 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-07-27 09:54:13 +0200 |
commit | bd6cc52de53fe260e63ae986bff84cf142690f78 (patch) | |
tree | 78c2fe9f959e6ab09e74c25b95b6529cafd92983 /arch/mips/lib | |
parent | bdf8405e34df9eeb75cb71801363509a7ab91536 (diff) | |
download | barebox-bd6cc52de53fe260e63ae986bff84cf142690f78.tar.gz barebox-bd6cc52de53fe260e63ae986bff84cf142690f78.tar.xz |
MIPS: add initial exceptions handling
Checking exception handling:
$ make qemu-malta_defconfig
$ make
...
$ qemu-system-mips -nodefaults -M malta -m 256 \
-nographic -serial stdio -bios ./barebox.bin
...
barebox:/ md -l 0x03
Ooops, address error on load or ifetch!
EPC = 0xa082783c
CP0_STATUS = 0x00000006
CP0_CAUSE = 0x00000410
CP0_CONFIG = 0x80008482
### ERROR ### Please RESET the board ###
Signed-off-by: Antony Pavlov <antonynpavlov@gmail.com>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/mips/lib')
-rw-r--r-- | arch/mips/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/mips/lib/genex.S | 31 | ||||
-rw-r--r-- | arch/mips/lib/traps.c | 107 |
3 files changed, 140 insertions, 0 deletions
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index b99bb71837..a31046b80e 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -5,6 +5,8 @@ obj-y += ashldi3.o obj-y += ashrdi3.o obj-y += memory.o obj-y += cpu-probe.o +obj-y += traps.o +obj-y += genex.o obj-$(CONFIG_CPU_MIPS32) += c-r4k.o obj-$(CONFIG_CPU_MIPS64) += c-r4k.o diff --git a/arch/mips/lib/genex.S b/arch/mips/lib/genex.S new file mode 100644 index 0000000000..d6f65a2ca4 --- /dev/null +++ b/arch/mips/lib/genex.S @@ -0,0 +1,31 @@ +#include <asm/asm.h> +#include <asm/regdef.h> +#include <asm/mipsregs.h> + + .text + .set macro + .set noat + .set noreorder + .align 5 + +/* Exception vector */ +NESTED(handle_reserved, 0, sp) + la k0, barebox_exc_handler + jal k0 + move a0, sp + /* will never return here */ + END(handle_reserved) + +/* General exception vector */ +NESTED(except_vec3_generic, 0, sp) + .set noat + mfc0 k1, CP0_CAUSE + la k0, exception_handlers + andi k1, k1, 0x7c + addu k0, k0, k1 + lw k0, (k0) + nop + jr k0 + nop + END(except_vec3_generic) + .set at diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c new file mode 100644 index 0000000000..4e167cc9f4 --- /dev/null +++ b/arch/mips/lib/traps.c @@ -0,0 +1,107 @@ +#include <common.h> + +#include <asm/mipsregs.h> + +void barebox_exc_handler(void *regs); + +/* + * Trap codes from OpenBSD trap.h + */ +#define T_INT 0 /* Interrupt pending */ +#define T_TLB_MOD 1 /* TLB modified fault */ +#define T_TLB_LD_MISS 2 /* TLB miss on load or ifetch */ +#define T_TLB_ST_MISS 3 /* TLB miss on a store */ +#define T_ADDR_ERR_LD 4 /* Address error on a load or ifetch */ +#define T_ADDR_ERR_ST 5 /* Address error on a store */ +#define T_BUS_ERR_IFETCH 6 /* Bus error on an ifetch */ +#define T_BUS_ERR_LD_ST 7 /* Bus error on a load or store */ +#define T_SYSCALL 8 /* System call */ +#define T_BREAK 9 /* Breakpoint */ +#define T_RES_INST 10 /* Reserved instruction exception */ +#define T_COP_UNUSABLE 11 /* Coprocessor unusable */ +#define T_OVFLOW 12 /* Arithmetic overflow */ +#define T_TRAP 13 /* Trap instruction */ +#define T_VCEI 14 /* Virtual coherency instruction */ +#define T_FPE 15 /* Floating point exception */ +#define T_IWATCH 16 /* Inst. Watch address reference */ +#define T_DWATCH 23 /* Data Watch address reference */ +#define T_VCED 31 /* Virtual coherency data */ + +#define CR_EXC_CODE 0x0000007c +#define CR_EXC_CODE_SHIFT 2 + +static char *get_exc_name(u32 cause) +{ + switch ((cause & CR_EXC_CODE) >> CR_EXC_CODE_SHIFT) { + + case T_INT: + return "interrupt pending"; + + case T_TLB_MOD: + return "TLB modified"; + + case T_TLB_LD_MISS: + return "TLB miss on load or ifetch"; + + case T_TLB_ST_MISS: + return "TLB miss on store"; + + case T_ADDR_ERR_LD: + return "address error on load or ifetch"; + + case T_ADDR_ERR_ST: + return "address error on store"; + + case T_BUS_ERR_IFETCH: + return "bus error on ifetch"; + + case T_BUS_ERR_LD_ST: + return "bus error on load or store"; + + case T_SYSCALL: + return "system call"; + + case T_BREAK: + return "breakpoint"; + + case T_RES_INST: + return "reserved instruction"; + + case T_COP_UNUSABLE: + return "coprocessor unusable"; + + case T_OVFLOW: + return "arithmetic overflow"; + + case T_TRAP: + return "trap instruction"; + + case T_VCEI: + return "virtual coherency instruction"; + + case T_FPE: + return "floating point"; + + case T_IWATCH: + return "iwatch"; + + case T_DWATCH: + return "dwatch"; + + case T_VCED: + return "virtual coherency data"; + } + + return "unknown exception"; +} + +void barebox_exc_handler(void *regs) +{ + printf("\nOoops, %s!\n", get_exc_name(read_c0_cause())); + printf("EPC = 0x%08x\n", read_c0_epc()); + printf("CP0_STATUS = 0x%08x\n", read_c0_status()); + printf("CP0_CAUSE = 0x%08x\n", read_c0_cause()); + printf("CP0_CONFIG = 0x%08x\n\n", read_c0_config()); + + hang(); +} |