aboutsummaryrefslogtreecommitdiff
path: root/target-xtensa/cpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'target-xtensa/cpu.h')
-rw-r--r--target-xtensa/cpu.h67
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)) {