nios2: add base exception handling code

Change-Id: I56b0ec1a3576a77ca7bd6f2c0217de8053406927
Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
Andrew Boie 2016-06-21 12:15:33 -07:00 committed by Inaky Perez-Gonzalez
commit e2ff2fdd91
5 changed files with 420 additions and 24 deletions

View file

@ -34,10 +34,11 @@ extern "C" {
#define STACK_ALIGN 4
#define _NANO_ERR_HW_EXCEPTION (0) /* MPU/Bus/Usage fault */
#define _NANO_ERR_CPU_EXCEPTION (0) /* Any unhandled exception */
#define _NANO_ERR_INVALID_TASK_EXIT (1) /* Invalid task exit */
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
#define _NANO_ERR_SPURIOUS_INT (4) /* Spurious interrupt */
#ifndef _ASMLANGUAGE
#include <stdint.h>
@ -93,8 +94,25 @@ void _arch_irq_enable(unsigned int irq);
void _arch_irq_disable(unsigned int irq);
struct __esf {
/* XXX - not defined yet */
uint32_t placeholder;
uint32_t ra; /* return address r31 */
uint32_t r0; /* zero register */
uint32_t r1; /* at */
uint32_t r2; /* return value */
uint32_t r3; /* return value */
uint32_t r4; /* register args */
uint32_t r5; /* register args */
uint32_t r6; /* register args */
uint32_t r7; /* register args */
uint32_t r8; /* Caller-saved general purpose */
uint32_t r9; /* Caller-saved general purpose */
uint32_t r10; /* Caller-saved general purpose */
uint32_t r11; /* Caller-saved general purpose */
uint32_t r12; /* Caller-saved general purpose */
uint32_t r13; /* Caller-saved general purpose */
uint32_t r14; /* Caller-saved general purpose */
uint32_t r15; /* Caller-saved general purpose */
uint32_t estatus;
uint32_t instr; /* Instruction being executed when exc occurred */
};
typedef struct __esf NANO_ESF;
@ -103,6 +121,48 @@ extern const NANO_ESF _default_esf;
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *esf);
enum nios2_exception_cause {
NIOS2_EXCEPTION_UNKNOWN = -1,
NIOS2_EXCEPTION_RESET = 0,
NIOS2_EXCEPTION_CPU_ONLY_RESET_REQUEST = 1,
NIOS2_EXCEPTION_INTERRUPT = 2,
NIOS2_EXCEPTION_TRAP_INST = 3,
NIOS2_EXCEPTION_UNIMPLEMENTED_INST = 4,
NIOS2_EXCEPTION_ILLEGAL_INST = 5,
NIOS2_EXCEPTION_MISALIGNED_DATA_ADDR = 6,
NIOS2_EXCEPTION_MISALIGNED_TARGET_PC = 7,
NIOS2_EXCEPTION_DIVISION_ERROR = 8,
NIOS2_EXCEPTION_SUPERVISOR_ONLY_INST_ADDR = 9,
NIOS2_EXCEPTION_SUPERVISOR_ONLY_INST = 10,
NIOS2_EXCEPTION_SUPERVISOR_ONLY_DATA_ADDR = 11,
NIOS2_EXCEPTION_TLB_MISS = 12,
NIOS2_EXCEPTION_TLB_EXECUTE_PERM_VIOLATION = 13,
NIOS2_EXCEPTION_TLB_READ_PERM_VIOLATION = 14,
NIOS2_EXCEPTION_TLB_WRITE_PERM_VIOLATION = 15,
NIOS2_EXCEPTION_MPU_INST_REGION_VIOLATION = 16,
NIOS2_EXCEPTION_MPU_DATA_REGION_VIOLATION = 17,
NIOS2_EXCEPTION_ECC_TLB_ERR = 18,
NIOS2_EXCEPTION_ECC_FETCH_ERR = 19,
NIOS2_EXCEPTION_ECC_REGISTER_FILE_ERR = 20,
NIOS2_EXCEPTION_ECC_DATA_ERR = 21,
NIOS2_EXCEPTION_ECC_DATA_CACHE_WRITEBACK_ERR = 22
};
/* Bitfield indicating which exception cause codes report a valid
* badaddr register. NIOS2_EXCEPTION_TLB_MISS and NIOS2_EXCEPTION_ECC_TLB_ERR
* are deliberately not included here, you need to check if TLBMISC.D=1
*/
#define NIOS2_BADADDR_CAUSE_MASK \
(BIT(NIOS2_EXCEPTION_SUPERVISOR_ONLY_DATA_ADDR) | \
BIT(NIOS2_EXCEPTION_MISALIGNED_DATA_ADDR) | \
BIT(NIOS2_EXCEPTION_MISALIGNED_TARGET_PC) | \
BIT(NIOS2_EXCEPTION_TLB_READ_PERM_VIOLATION) | \
BIT(NIOS2_EXCEPTION_TLB_WRITE_PERM_VIOLATION) | \
BIT(NIOS2_EXCEPTION_MPU_DATA_REGION_VIOLATION) | \
BIT(NIOS2_EXCEPTION_ECC_DATA_ERR))
#endif /* _ASMLANGUAGE */
#ifdef __cplusplus