diff --git a/arch/mips/src/mips32/up_dumpstate.c b/arch/mips/src/mips32/up_dumpstate.c index 061bce448fe..369d98d7f54 100644 --- a/arch/mips/src/mips32/up_dumpstate.c +++ b/arch/mips/src/mips32/up_dumpstate.c @@ -120,24 +120,24 @@ static inline void up_registerdump(void) lldbg("MFLO:%08x MFHI:%08x EPC:%08x STATUS:%08x\n", current_regs[REG_MFLO], current_regs[REG_MFHI], current_regs[REG_EPC], current_regs[REG_STATUS]); - lldbg("AT:%08x V0:$08x V1:%08x A0:%08x A1:%08x A2:%08x A3:%08x\n", + lldbg("AT:%08x V0:%08x V1:%08x A0:%08x A1:%08x A2:%08x A3:%08x\n", current_regs[REG_AT], current_regs[REG_V0], current_regs[REG_V1], current_regs[REG_A0], current_regs[REG_A1], current_regs[REG_A2], current_regs[REG_A3]); - lldbg("T0:%08x T1:$08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x T7:%08x\n", + lldbg("T0:%08x T1:%08x T2:%08x T3:%08x T4:%08x T5:%08x T6:%08x T7:%08x\n", current_regs[REG_T0], current_regs[REG_T1], current_regs[REG_T2], current_regs[REG_T3], current_regs[REG_T4], current_regs[REG_T5], current_regs[REG_T6], current_regs[REG_T7]); - lldbg("S0:%08x S1:$08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", + lldbg("S0:%08x S1:%08x S2:%08x S3:%08x S4:%08x S5:%08x S6:%08x S7:%08x\n", current_regs[REG_S0], current_regs[REG_S1], current_regs[REG_S2], current_regs[REG_S3], current_regs[REG_S4], current_regs[REG_S5], current_regs[REG_S6], current_regs[REG_S7]); #ifdef MIPS32_SAVE_GP - lldbg("T8:%08x T9:$08x GP:%08x SP:%08x FP:%08x RA:%08x\n", + lldbg("T8:%08x T9:%08x GP:%08x SP:%08x FP:%08x RA:%08x\n", current_regs[REG_T8], current_regs[REG_T9], current_regs[REG_GP], current_regs[REG_SP], current_regs[REG_FP], current_regs[REG_RA]); #else - lldbg("T8:%08x T9:$08x SP:%08x FP:%08x RA:%08x\n", + lldbg("T8:%08x T9:%08x SP:%08x FP:%08x RA:%08x\n", current_regs[REG_T8], current_regs[REG_T9], current_regs[REG_SP], current_regs[REG_FP], current_regs[REG_RA]); #endif diff --git a/arch/mips/src/mips32/up_initialstate.c b/arch/mips/src/mips32/up_initialstate.c index 0be7b3a2739..cc0cd227e14 100644 --- a/arch/mips/src/mips32/up_initialstate.c +++ b/arch/mips/src/mips32/up_initialstate.c @@ -123,10 +123,12 @@ void up_initial_state(_TCB *tcb) /* Set the initial value of the status register. It will be the same * as the current status register with some changes: * - * 1. Make sure the IE is set (it should be) - * 2. Clear the BEV bit (it should be) - * 3. Set the interrupt mask bits (depending on configuration) - * 4. Set the EXL bit + * 1. Make sure the IE is set + * 2. Clear the BEV bit (This bit should already be clear) + * 3. Clear the UM bit so that the new task executes in kernel mode + * (This bit should already be clear) + * 4. Set the interrupt mask bits (depending on configuration) + * 5. Set the EXL bit (This will not be set) * * The EXL bit is set because this new STATUS register will be * instantiated in kernel mode inside of an interrupt handler. EXL @@ -135,10 +137,10 @@ void up_initial_state(_TCB *tcb) regval = cp0_getstatus(); #ifdef CONFIG_SUPPRESS_INTERRUPTS - regval &= ~(CP0_STATUS_IM_ALL | CP0_STATUS_BEV); + regval &= ~(CP0_STATUS_IM_ALL | CP0_STATUS_BEV | CP0_STATUS_UM); regval |= (CP0_STATUS_IE | CP0_STATUS_EXL | CP0_STATUS_IM_SWINTS); #else - regval &= ~(CP0_STATUS_BEV); + regval &= ~(CP0_STATUS_BEV | CP0_STATUS_UM); regval |= (CP0_STATUS_IE | CP0_STATUS_EXL | CP0_STATUS_IM_ALL); #endif xcp->regs[REG_STATUS] = regval; diff --git a/arch/mips/src/pic32mx/Make.defs b/arch/mips/src/pic32mx/Make.defs index f9d59cc7298..a021dcb830a 100644 --- a/arch/mips/src/pic32mx/Make.defs +++ b/arch/mips/src/pic32mx/Make.defs @@ -61,7 +61,7 @@ endif # Required PIC32MX files CHIP_ASRCS = -CHIP_CSRCS = pic32mx-irq.c pic32mx-decodeirq.c pic32mx-dobev.c pic32mx-gpio.c \ +CHIP_CSRCS = pic32mx-irq.c pic32mx-decodeirq.c pic32mx-exception.c pic32mx-gpio.c \ pic32mx-lowconsole.c pic32mx-lowinit.c pic32mx-serial.c pic32mx-timerisr.c # Configuration-dependent PIC32MX files diff --git a/arch/mips/src/pic32mx/pic32mx-dobev.c b/arch/mips/src/pic32mx/pic32mx-exception.S similarity index 83% rename from arch/mips/src/pic32mx/pic32mx-dobev.c rename to arch/mips/src/pic32mx/pic32mx-exception.S index 5107a09622a..693b4972b8e 100644 --- a/arch/mips/src/pic32mx/pic32mx-dobev.c +++ b/arch/mips/src/pic32mx/pic32mx-exception.S @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/mips/src/pic32mx/pic32mx-dobev.c + * arch/mips/src/pic32mx/pic32mx-exception.c * * Copyright (C) 2011 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -76,14 +76,14 @@ ****************************************************************************/ /************************************************************************************ - * Name: pic32mx_dobev + * Name: pic32mx_exception * * Description: * Called from assembly language logic on all other exceptions. * ************************************************************************************/ -uint32_t *pic32mx_dobev(uint32_t *regs) +uint32_t *pic32mx_exception(uint32_t *regs) { #ifdef CONFIG_DEBUG uint32_t cause; @@ -107,92 +107,93 @@ uint32_t *pic32mx_dobev(uint32_t *regs) { case CP0_CAUSE_EXCCODE_INT: /* Interrupt */ llvdbg("EXCEPTION: Interrupt" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_TLBL: /* TLB exception (load or instruction fetch) */ llvdbg("EXCEPTION: TLB exception (load or instruction fetch)" - " CAUSE:%08x EPC:%0ex\n", cause, epc); + " CAUSE: %08x EPC:%08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_TLBS: /* TLB exception (store) */ llvdbg("EXCEPTION: TLB exception (store)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_ADEL: /* Address error exception (load or instruction fetch) */ llvdbg("EXCEPTION: Address error exception (load or instruction fetch)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_ADES: /* Address error exception (store) */ llvdbg("EXCEPTION: Address error exception (store)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_IBE: /* Bus error exception (instruction fetch) */ llvdbg("EXCEPTION: Bus error exception (instruction fetch)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_DBE: /* Bus error exception (data reference: load or store) */ llvdbg("EXCEPTION: Bus error exception (data reference: load or store)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_SYS: /* Syscall exception */ llvdbg("EXCEPTION: Syscall exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_BP: /* Breakpoint exception */ llvdbg("EXCEPTION: Breakpoint exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_RI: /* Reserved instruction exception */ llvdbg("EXCEPTION: Reserved instruction exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_CPU: /* Coprocessor Unusable exception */ llvdbg("EXCEPTION: Coprocessor Unusable exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_OV: /* Arithmetic Overflow exception */ llvdbg("EXCEPTION: Arithmetic Overflow exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_TR: /* Trap exception */ llvdbg("EXCEPTION: Trap exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_FPE: /* Floating point exception */ llvdbg("EXCEPTION: Floating point exception" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_C2E: /* Precise Coprocessor 2 exceptions */ llvdbg("EXCEPTION: Precise Coprocessor 2 exceptions" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_MDMX: /* MDMX Unusable (MIPS64) */ llvdbg("EXCEPTION: MDMX Unusable (MIPS64)" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_WATCH: /* WatchHi/WatchLo address */ llvdbg("EXCEPTION: WatchHi/WatchLo address" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_MCHECK: /* Machine check */ llvdbg("EXCEPTION: Machine check" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; case CP0_CAUSE_EXCCODE_CACHEERR: /* Cache error */ llvdbg("EXCEPTION: Cache error" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; default: llvdbg("EXCEPTION: Unknown" - " CAUSE: %08x EPC: %0ex\n", cause, epc); + " CAUSE: %08x EPC: %08x\n", cause, epc); break; } #else - lldbg("EXCEPTION: CAUSE: %08x EPC: %0ex\n", cause, epc); + lldbg("EXCEPTION: CAUSE: %08x EPC: %08x\n", cause, epc); #endif #endif - /* Crash */ + /* Crash with currents_regs set so that we can dump the register contents. */ + current_regs = regs; PANIC(OSERR_ERREXCEPTION); return regs; /* Won't get here */ } diff --git a/arch/mips/src/pic32mx/pic32mx-head.S b/arch/mips/src/pic32mx/pic32mx-head.S index 2491cf45140..86000498052 100644 --- a/arch/mips/src/pic32mx/pic32mx-head.S +++ b/arch/mips/src/pic32mx/pic32mx-head.S @@ -125,7 +125,7 @@ /* Imported symbols */ .global os_start - .global pic32mx_dobev + .global pic32mx_exception .global pic32mx_decodeirq #ifdef CONFIG_PIC32MX_NMIHANDLER .global pic32mx_donmi @@ -156,11 +156,35 @@ __reset: nop .end __reset + +/**************************************************************************** + * Name: _gen_exception + * + * Description: + * General Exception Vector Handler. Jumps to _exception_handler + * + * Input Parameters: + * None + * + * Returned Value: + * Does not return + * + ****************************************************************************/ + + .section .gen_excpt,"ax",@progbits + .set noreorder + .ent _gen_exception +_gen_exception: + la k0, _exception_handler + jr k0 + nop + .end _gen_exception + /**************************************************************************** * Name: _bev_exception * * Description: - * Boot Exception Vector Handler. Jumps to _bev_handler + * Boot Exception Vector Handler. Jumps to _exception_handler * * Input Parameters: * None @@ -174,7 +198,7 @@ __reset: .set noreorder .ent _bev_exception _bev_exception: - la k0, _bev_handler + la k0, _exception_handler jr k0 nop .end _bev_exception @@ -419,29 +443,29 @@ __start: .end __start /**************************************************************************** - * Name: _bev_handler + * Name: _exception_handler * * Description: - * BEV exception handler. Calls pic32mx_dobev() + * BEV/General exception handler. Calls pic32mx_exception() * ****************************************************************************/ .section .bev_handler, "ax", @progbits .set noreorder - .ent _bev_handler -_bev_handler: + .ent _exception_handler +_exception_handler: EXCPT_PROLOGUE t0 /* Save registers on stack, enable nested interrupts */ move a0, sp /* Pass register save structure as the parameter 1 */ USE_INTSTACK t0, t1, t2 /* Switch to the interrupt stack */ - la t0, pic32mx_dobev /* Call up_dobev(regs) */ + la t0, pic32mx_exception /* Call pic32mx_exception(regs) */ jalr ra, t0 nop #ifdef CONFIG_PIC32MX_NESTED_INTERRUPTS di /* Prohibit nested interrupts from here */ #endif RESTORE_STACK t0, t1 /* Undo the operations of USE_STACK */ - EXCPT_EPILOGUE v0 /* Return to the context returned by up_dobev() */ - .end _bev_handler + EXCPT_EPILOGUE v0 /* Return to the context returned by pic32mx_exception() */ + .end _exception_handler /**************************************************************************** * Name: _int_handler diff --git a/arch/mips/src/pic32mx/pic32mx-internal.h b/arch/mips/src/pic32mx/pic32mx-internal.h index 8d9687ae4c3..004d4eeea95 100644 --- a/arch/mips/src/pic32mx/pic32mx-internal.h +++ b/arch/mips/src/pic32mx/pic32mx-internal.h @@ -232,14 +232,14 @@ EXTERN void pic32mx_boardinitialize(void); EXTERN uint32_t *pic32mx_decodeirq(uint32_t *regs); /************************************************************************************ - * Name: pic32mx_dobev + * Name: pic32mx_exception * * Description: * Called from assembly language logic on all other exceptions. * ************************************************************************************/ -EXTERN uint32_t *pic32mx_dobev(uint32_t *regs); +EXTERN uint32_t *pic32mx_exception(uint32_t *regs); /************************************************************************************ * Name: pic32mx_configgpio diff --git a/configs/pcblogic-pic32mx/ostest/ld.script b/configs/pcblogic-pic32mx/ostest/ld.script index e639ba37cfe..6984d9f4109 100644 --- a/configs/pcblogic-pic32mx/ostest/ld.script +++ b/configs/pcblogic-pic32mx/ostest/ld.script @@ -62,13 +62,14 @@ MEMORY * * Exceptions assume: * - * STATUS: BEV=1 and EXL=0 + * STATUS: BEV=0/1 and EXL=0 * CAUSE: IV=1 * JTAG: ProbEn=0 * And multi-vector support disabled */ - kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 896 + kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 384 + kseg1_genexcpt (rx) : ORIGIN = 0xbfc00180, LENGTH = 128 kseg1_bevexcpt (rx) : ORIGIN = 0xbfc00380, LENGTH = 128 kseg1_intexcpt (rx) : ORIGIN = 0xbfc00400, LENGTH = 128 kseg1_dbgexcpt (rx) : ORIGIN = 0xbfc00480, LENGTH = 16 @@ -119,6 +120,11 @@ SECTIONS /* KSEG1 exception handler "trampolines" */ + .gen_excpt : + { + KEEP (*(.gen_excpt)) + } > kseg1_genexcpt + .bev_excpt : { KEEP (*(.bev_excpt)) diff --git a/configs/pic32-starterkit/ostest/ld.script b/configs/pic32-starterkit/ostest/ld.script index a7d55d8b344..eb764bd203b 100644 --- a/configs/pic32-starterkit/ostest/ld.script +++ b/configs/pic32-starterkit/ostest/ld.script @@ -62,14 +62,14 @@ MEMORY * * Exceptions assume: * - * STATUS: BEV=1 and EXL=0 + * STATUS: BEV=0/1 and EXL=0 * CAUSE: IV=1 * JTAG: ProbEn=0 * And multi-vector support disabled */ - kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 896 - kseg1_bevexcpt (rx) : ORIGIN = 0xbfc00380, LENGTH = 128 + kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 384 + kseg1_genexcpt (rx) : ORIGIN = 0xbfc00180, LENGTH = 128 kseg1_intexcpt (rx) : ORIGIN = 0xbfc00400, LENGTH = 128 kseg1_dbgexcpt (rx) : ORIGIN = 0xbfc00480, LENGTH = 16 kseg0_bootmem (rx) : ORIGIN = 0x9fc00490, LENGTH = 8192-1168 @@ -119,6 +119,11 @@ SECTIONS /* KSEG1 exception handler "trampolines" */ + .gen_excpt : + { + KEEP (*(.gen_excpt)) + } > kseg1_genexcpt + .bev_excpt : { KEEP (*(.bev_excpt)) diff --git a/configs/sure-pic32mx/ostest/ld.script b/configs/sure-pic32mx/ostest/ld.script index 0af4bd1a8a7..d5b41f61267 100644 --- a/configs/sure-pic32mx/ostest/ld.script +++ b/configs/sure-pic32mx/ostest/ld.script @@ -62,14 +62,14 @@ MEMORY * * Exceptions assume: * - * STATUS: BEV=1 and EXL=0 + * STATUS: BEV=0/1 and EXL=0 * CAUSE: IV=1 * JTAG: ProbEn=0 * And multi-vector support disabled */ - kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 896 - kseg1_bevexcpt (rx) : ORIGIN = 0xbfc00380, LENGTH = 128 + kseg1_reset (rx) : ORIGIN = 0xbfc00000, LENGTH = 384 + kseg1_genexcpt (rx) : ORIGIN = 0xbfc00180, LENGTH = 128 kseg1_intexcpt (rx) : ORIGIN = 0xbfc00400, LENGTH = 128 kseg1_dbgexcpt (rx) : ORIGIN = 0xbfc00480, LENGTH = 16 kseg0_bootmem (rx) : ORIGIN = 0x9fc00490, LENGTH = 8192-1168 @@ -119,6 +119,11 @@ SECTIONS /* KSEG1 exception handler "trampolines" */ + .gen_excpt : + { + KEEP (*(.gen_excpt)) + } > kseg1_genexcpt + .bev_excpt : { KEEP (*(.bev_excpt))