mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-09 02:24:58 -06:00
target-xtensa: implement exceptions
- mark privileged opcodes with ring check; - make debug exception on exception handler entry. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
This commit is contained in:
parent
f0a548b93d
commit
40643d7c0f
6 changed files with 242 additions and 6 deletions
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue