diff options
Diffstat (limited to 'target-xtensa/cpu.h')
-rw-r--r-- | target-xtensa/cpu.h | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h index 939222ca8c..cae663706b 100644 --- a/target-xtensa/cpu.h +++ b/target-xtensa/cpu.h @@ -108,7 +108,12 @@ enum { enum { SAR = 3, SCOMPARE1 = 12, + EPC1 = 177, + DEPC = 192, + EXCSAVE1 = 209, PS = 230, + EXCCAUSE = 232, + EXCVADDR = 238, }; #define PS_INTLEVEL 0xf @@ -129,9 +134,60 @@ enum { #define PS_WOE 0x40000 +enum { + /* Static vectors */ + EXC_RESET, + EXC_MEMORY_ERROR, + + /* Dynamic vectors */ + EXC_WINDOW_OVERFLOW4, + EXC_WINDOW_UNDERFLOW4, + EXC_WINDOW_OVERFLOW8, + EXC_WINDOW_UNDERFLOW8, + EXC_WINDOW_OVERFLOW12, + EXC_WINDOW_UNDERFLOW12, + EXC_IRQ, + EXC_KERNEL, + EXC_USER, + EXC_DOUBLE, + EXC_MAX +}; + +enum { + ILLEGAL_INSTRUCTION_CAUSE = 0, + SYSCALL_CAUSE, + INSTRUCTION_FETCH_ERROR_CAUSE, + LOAD_STORE_ERROR_CAUSE, + LEVEL1_INTERRUPT_CAUSE, + ALLOCA_CAUSE, + INTEGER_DIVIDE_BY_ZERO_CAUSE, + PRIVILEGED_CAUSE = 8, + LOAD_STORE_ALIGNMENT_CAUSE, + + INSTR_PIF_DATA_ERROR_CAUSE = 12, + LOAD_STORE_PIF_DATA_ERROR_CAUSE, + INSTR_PIF_ADDR_ERROR_CAUSE, + LOAD_STORE_PIF_ADDR_ERROR_CAUSE, + + INST_TLB_MISS_CAUSE, + INST_TLB_MULTI_HIT_CAUSE, + INST_FETCH_PRIVILEGE_CAUSE, + INST_FETCH_PROHIBITED_CAUSE = 20, + LOAD_STORE_TLB_MISS_CAUSE = 24, + LOAD_STORE_TLB_MULTI_HIT_CAUSE, + LOAD_STORE_PRIVILEGE_CAUSE, + LOAD_PROHIBITED_CAUSE = 28, + STORE_PROHIBITED_CAUSE, + + COPROCESSOR0_DISABLED = 32, +}; + typedef struct XtensaConfig { const char *name; uint64_t options; + int excm_level; + int ndepc; + uint32_t exception_vector[EXC_MAX]; } XtensaConfig; typedef struct CPUXtensaState { @@ -141,6 +197,8 @@ typedef struct CPUXtensaState { uint32_t sregs[256]; uint32_t uregs[256]; + int exception_taken; + CPU_COMMON } CPUXtensaState; @@ -164,6 +222,15 @@ static inline bool xtensa_option_enabled(const XtensaConfig *config, int opt) return (config->options & XTENSA_OPTION_BIT(opt)) != 0; } +static inline int xtensa_get_cintlevel(const CPUState *env) +{ + int level = (env->sregs[PS] & PS_INTLEVEL) >> PS_INTLEVEL_SHIFT; + if ((env->sregs[PS] & PS_EXCM) && env->config->excm_level > level) { + level = env->config->excm_level; + } + return level; +} + static inline int xtensa_get_ring(const CPUState *env) { if (xtensa_option_enabled(env->config, XTENSA_OPTION_MMU)) { |