mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-08 22:25:27 +00:00
target-arm: Update interrupt handling to use target EL
Updated the interrupt handling to utilize and report through the target EL exception field. This includes consolidating and cleaning up code where needed. Target EL is now calculated once in arm_cpu_exec_interrupt() and do_interrupt was updated to use the target_el exception field. The necessary code from arm_excp_target_el() was merged in where needed and the function removed. Backports commit 012a906b19e99b126403ff4a257617dab9b34163 from qemu
This commit is contained in:
parent
9a97c94297
commit
5ad81f095a
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_aarch64
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_aarch64
|
||||
#define arm_env_get_cpu arm_env_get_cpu_aarch64
|
||||
#define arm_excp_target_el arm_excp_target_el_aarch64
|
||||
#define arm_excp_unmasked arm_excp_unmasked_aarch64
|
||||
#define arm_feature arm_feature_aarch64
|
||||
#define arm_free_cc arm_free_cc_aarch64
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_aarch64
|
||||
#define arm_lduw_code arm_lduw_code_aarch64
|
||||
#define arm_log_exception arm_log_exception_aarch64
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_aarch64
|
||||
#define arm_reg_read arm_reg_read_aarch64
|
||||
#define arm_reg_reset arm_reg_reset_aarch64
|
||||
#define arm_reg_write arm_reg_write_aarch64
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_aarch64eb
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_aarch64eb
|
||||
#define arm_env_get_cpu arm_env_get_cpu_aarch64eb
|
||||
#define arm_excp_target_el arm_excp_target_el_aarch64eb
|
||||
#define arm_excp_unmasked arm_excp_unmasked_aarch64eb
|
||||
#define arm_feature arm_feature_aarch64eb
|
||||
#define arm_free_cc arm_free_cc_aarch64eb
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_aarch64eb
|
||||
#define arm_lduw_code arm_lduw_code_aarch64eb
|
||||
#define arm_log_exception arm_log_exception_aarch64eb
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_aarch64eb
|
||||
#define arm_reg_read arm_reg_read_aarch64eb
|
||||
#define arm_reg_reset arm_reg_reset_aarch64eb
|
||||
#define arm_reg_write arm_reg_write_aarch64eb
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_arm
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_arm
|
||||
#define arm_env_get_cpu arm_env_get_cpu_arm
|
||||
#define arm_excp_target_el arm_excp_target_el_arm
|
||||
#define arm_excp_unmasked arm_excp_unmasked_arm
|
||||
#define arm_feature arm_feature_arm
|
||||
#define arm_free_cc arm_free_cc_arm
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_arm
|
||||
#define arm_lduw_code arm_lduw_code_arm
|
||||
#define arm_log_exception arm_log_exception_arm
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_arm
|
||||
#define arm_reg_read arm_reg_read_arm
|
||||
#define arm_reg_reset arm_reg_reset_arm
|
||||
#define arm_reg_write arm_reg_write_arm
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_armeb
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_armeb
|
||||
#define arm_env_get_cpu arm_env_get_cpu_armeb
|
||||
#define arm_excp_target_el arm_excp_target_el_armeb
|
||||
#define arm_excp_unmasked arm_excp_unmasked_armeb
|
||||
#define arm_feature arm_feature_armeb
|
||||
#define arm_free_cc arm_free_cc_armeb
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_armeb
|
||||
#define arm_lduw_code arm_lduw_code_armeb
|
||||
#define arm_log_exception arm_log_exception_armeb
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_armeb
|
||||
#define arm_reg_read arm_reg_read_armeb
|
||||
#define arm_reg_reset arm_reg_reset_armeb
|
||||
#define arm_reg_write arm_reg_write_armeb
|
||||
|
|
|
@ -147,7 +147,6 @@ symbols = (
|
|||
'arm_debug_target_el',
|
||||
'arm_el_is_aa64',
|
||||
'arm_env_get_cpu',
|
||||
'arm_excp_target_el',
|
||||
'arm_excp_unmasked',
|
||||
'arm_feature',
|
||||
'arm_free_cc',
|
||||
|
@ -165,6 +164,7 @@ symbols = (
|
|||
'arm_ldl_code',
|
||||
'arm_lduw_code',
|
||||
'arm_log_exception',
|
||||
'arm_phys_excp_target_el',
|
||||
'arm_reg_read',
|
||||
'arm_reg_reset',
|
||||
'arm_reg_write',
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_m68k
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_m68k
|
||||
#define arm_env_get_cpu arm_env_get_cpu_m68k
|
||||
#define arm_excp_target_el arm_excp_target_el_m68k
|
||||
#define arm_excp_unmasked arm_excp_unmasked_m68k
|
||||
#define arm_feature arm_feature_m68k
|
||||
#define arm_free_cc arm_free_cc_m68k
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_m68k
|
||||
#define arm_lduw_code arm_lduw_code_m68k
|
||||
#define arm_log_exception arm_log_exception_m68k
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_m68k
|
||||
#define arm_reg_read arm_reg_read_m68k
|
||||
#define arm_reg_reset arm_reg_reset_m68k
|
||||
#define arm_reg_write arm_reg_write_m68k
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_mips
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_mips
|
||||
#define arm_env_get_cpu arm_env_get_cpu_mips
|
||||
#define arm_excp_target_el arm_excp_target_el_mips
|
||||
#define arm_excp_unmasked arm_excp_unmasked_mips
|
||||
#define arm_feature arm_feature_mips
|
||||
#define arm_free_cc arm_free_cc_mips
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_mips
|
||||
#define arm_lduw_code arm_lduw_code_mips
|
||||
#define arm_log_exception arm_log_exception_mips
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_mips
|
||||
#define arm_reg_read arm_reg_read_mips
|
||||
#define arm_reg_reset arm_reg_reset_mips
|
||||
#define arm_reg_write arm_reg_write_mips
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_mips64
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_mips64
|
||||
#define arm_env_get_cpu arm_env_get_cpu_mips64
|
||||
#define arm_excp_target_el arm_excp_target_el_mips64
|
||||
#define arm_excp_unmasked arm_excp_unmasked_mips64
|
||||
#define arm_feature arm_feature_mips64
|
||||
#define arm_free_cc arm_free_cc_mips64
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_mips64
|
||||
#define arm_lduw_code arm_lduw_code_mips64
|
||||
#define arm_log_exception arm_log_exception_mips64
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_mips64
|
||||
#define arm_reg_read arm_reg_read_mips64
|
||||
#define arm_reg_reset arm_reg_reset_mips64
|
||||
#define arm_reg_write arm_reg_write_mips64
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_mips64el
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_mips64el
|
||||
#define arm_env_get_cpu arm_env_get_cpu_mips64el
|
||||
#define arm_excp_target_el arm_excp_target_el_mips64el
|
||||
#define arm_excp_unmasked arm_excp_unmasked_mips64el
|
||||
#define arm_feature arm_feature_mips64el
|
||||
#define arm_free_cc arm_free_cc_mips64el
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_mips64el
|
||||
#define arm_lduw_code arm_lduw_code_mips64el
|
||||
#define arm_log_exception arm_log_exception_mips64el
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_mips64el
|
||||
#define arm_reg_read arm_reg_read_mips64el
|
||||
#define arm_reg_reset arm_reg_reset_mips64el
|
||||
#define arm_reg_write arm_reg_write_mips64el
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_mipsel
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_mipsel
|
||||
#define arm_env_get_cpu arm_env_get_cpu_mipsel
|
||||
#define arm_excp_target_el arm_excp_target_el_mipsel
|
||||
#define arm_excp_unmasked arm_excp_unmasked_mipsel
|
||||
#define arm_feature arm_feature_mipsel
|
||||
#define arm_free_cc arm_free_cc_mipsel
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_mipsel
|
||||
#define arm_lduw_code arm_lduw_code_mipsel
|
||||
#define arm_log_exception arm_log_exception_mipsel
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_mipsel
|
||||
#define arm_reg_read arm_reg_read_mipsel
|
||||
#define arm_reg_reset arm_reg_reset_mipsel
|
||||
#define arm_reg_write arm_reg_write_mipsel
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_powerpc
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_powerpc
|
||||
#define arm_env_get_cpu arm_env_get_cpu_powerpc
|
||||
#define arm_excp_target_el arm_excp_target_el_powerpc
|
||||
#define arm_excp_unmasked arm_excp_unmasked_powerpc
|
||||
#define arm_feature arm_feature_powerpc
|
||||
#define arm_free_cc arm_free_cc_powerpc
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_powerpc
|
||||
#define arm_lduw_code arm_lduw_code_powerpc
|
||||
#define arm_log_exception arm_log_exception_powerpc
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_powerpc
|
||||
#define arm_reg_read arm_reg_read_powerpc
|
||||
#define arm_reg_reset arm_reg_reset_powerpc
|
||||
#define arm_reg_write arm_reg_write_powerpc
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_sparc
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_sparc
|
||||
#define arm_env_get_cpu arm_env_get_cpu_sparc
|
||||
#define arm_excp_target_el arm_excp_target_el_sparc
|
||||
#define arm_excp_unmasked arm_excp_unmasked_sparc
|
||||
#define arm_feature arm_feature_sparc
|
||||
#define arm_free_cc arm_free_cc_sparc
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_sparc
|
||||
#define arm_lduw_code arm_lduw_code_sparc
|
||||
#define arm_log_exception arm_log_exception_sparc
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_sparc
|
||||
#define arm_reg_read arm_reg_read_sparc
|
||||
#define arm_reg_reset arm_reg_reset_sparc
|
||||
#define arm_reg_write arm_reg_write_sparc
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_sparc64
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_sparc64
|
||||
#define arm_env_get_cpu arm_env_get_cpu_sparc64
|
||||
#define arm_excp_target_el arm_excp_target_el_sparc64
|
||||
#define arm_excp_unmasked arm_excp_unmasked_sparc64
|
||||
#define arm_feature arm_feature_sparc64
|
||||
#define arm_free_cc arm_free_cc_sparc64
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_sparc64
|
||||
#define arm_lduw_code arm_lduw_code_sparc64
|
||||
#define arm_log_exception arm_log_exception_sparc64
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_sparc64
|
||||
#define arm_reg_read arm_reg_read_sparc64
|
||||
#define arm_reg_reset arm_reg_reset_sparc64
|
||||
#define arm_reg_write arm_reg_write_sparc64
|
||||
|
|
|
@ -207,31 +207,51 @@ bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
|
|||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
CPUClass *cc = CPU_GET_CLASS(env->uc, cs);
|
||||
uint32_t cur_el = arm_current_el(env);
|
||||
bool secure = arm_is_secure(env);
|
||||
uint32_t target_el;
|
||||
uint32_t excp_idx;
|
||||
bool ret = false;
|
||||
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ
|
||||
&& arm_excp_unmasked(cs, EXCP_FIQ)) {
|
||||
cs->exception_index = EXCP_FIQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ) {
|
||||
excp_idx = EXCP_FIQ;
|
||||
target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& arm_excp_unmasked(cs, EXCP_IRQ)) {
|
||||
cs->exception_index = EXCP_IRQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
excp_idx = EXCP_IRQ;
|
||||
target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_VIRQ
|
||||
&& arm_excp_unmasked(cs, EXCP_VIRQ)) {
|
||||
cs->exception_index = EXCP_VIRQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_VIRQ) {
|
||||
excp_idx = EXCP_VIRQ;
|
||||
target_el = 1;
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_VFIQ
|
||||
&& arm_excp_unmasked(cs, EXCP_VFIQ)) {
|
||||
cs->exception_index = EXCP_VFIQ;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
if (interrupt_request & CPU_INTERRUPT_VFIQ) {
|
||||
excp_idx = EXCP_VFIQ;
|
||||
target_el = 1;
|
||||
if (arm_excp_unmasked(cs, excp_idx, target_el)) {
|
||||
cs->exception_index = excp_idx;
|
||||
env->exception.target_el = target_el;
|
||||
cc->do_interrupt(cs);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -1016,7 +1016,8 @@ static inline bool access_secure_reg(CPUARMState *env)
|
|||
(_val))
|
||||
|
||||
void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
|
||||
unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx);
|
||||
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
uint32_t cur_el, bool secure);
|
||||
|
||||
/* Interface between CPU and Interrupt controller. */
|
||||
void armv7m_nvic_set_pending(void *opaque, int irq);
|
||||
|
@ -1498,11 +1499,11 @@ bool write_cpustate_to_list(ARMCPU *cpu);
|
|||
# define TARGET_VIRT_ADDR_SPACE_BITS 32
|
||||
#endif
|
||||
|
||||
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx)
|
||||
static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
|
||||
unsigned int target_el)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
unsigned int cur_el = arm_current_el(env);
|
||||
unsigned int target_el = arm_excp_target_el(cs, excp_idx);
|
||||
bool secure = arm_is_secure(env);
|
||||
uint32_t scr;
|
||||
uint32_t hcr;
|
||||
|
|
|
@ -519,7 +519,7 @@ void aarch64_cpu_do_interrupt(CPUState *cs)
|
|||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
ARMCPU *cpu = ARM_CPU(env->uc, cs);
|
||||
unsigned int new_el = arm_excp_target_el(cs, cs->exception_index);
|
||||
unsigned int new_el = env->exception.target_el;
|
||||
target_ulong addr = env->cp15.vbar_el[new_el];
|
||||
unsigned int new_mode = aarch64_pstate_mode(new_el, true);
|
||||
|
||||
|
|
|
@ -3562,7 +3562,8 @@ uint32_t HELPER(get_r13_banked)(CPUARMState *env, uint32_t mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
|
||||
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
uint32_t cur_el, bool secure)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -3687,8 +3688,8 @@ const int8_t target_el_table[2][2][2][2][2][4] = {
|
|||
/*
|
||||
* Determine the target EL for physical exceptions
|
||||
*/
|
||||
static inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
uint32_t cur_el, bool secure)
|
||||
uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
||||
uint32_t cur_el, bool secure)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
int rw = ((env->cp15.scr_el3 & SCR_RW) == SCR_RW);
|
||||
|
@ -3723,39 +3724,6 @@ static inline uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx,
|
|||
return target_el;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine the target EL for a given exception type.
|
||||
*/
|
||||
unsigned int arm_excp_target_el(CPUState *cs, unsigned int excp_idx)
|
||||
{
|
||||
CPUARMState *env = cs->env_ptr;
|
||||
unsigned int cur_el = arm_current_el(env);
|
||||
unsigned int target_el;
|
||||
bool secure = arm_is_secure(env);
|
||||
|
||||
switch (excp_idx) {
|
||||
case EXCP_HVC:
|
||||
case EXCP_HYP_TRAP:
|
||||
target_el = 2;
|
||||
break;
|
||||
case EXCP_SMC:
|
||||
target_el = 3;
|
||||
break;
|
||||
case EXCP_FIQ:
|
||||
case EXCP_IRQ:
|
||||
target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
|
||||
break;
|
||||
case EXCP_VIRQ:
|
||||
case EXCP_VFIQ:
|
||||
target_el = 1;
|
||||
break;
|
||||
default:
|
||||
target_el = MAX(cur_el, 1);
|
||||
break;
|
||||
}
|
||||
return target_el;
|
||||
}
|
||||
|
||||
static void v7m_push(CPUARMState *env, uint32_t val)
|
||||
{
|
||||
CPUState *cs = CPU(arm_env_get_cpu(env));
|
||||
|
|
|
@ -141,7 +141,6 @@
|
|||
#define arm_debug_target_el arm_debug_target_el_x86_64
|
||||
#define arm_el_is_aa64 arm_el_is_aa64_x86_64
|
||||
#define arm_env_get_cpu arm_env_get_cpu_x86_64
|
||||
#define arm_excp_target_el arm_excp_target_el_x86_64
|
||||
#define arm_excp_unmasked arm_excp_unmasked_x86_64
|
||||
#define arm_feature arm_feature_x86_64
|
||||
#define arm_free_cc arm_free_cc_x86_64
|
||||
|
@ -159,6 +158,7 @@
|
|||
#define arm_ldl_code arm_ldl_code_x86_64
|
||||
#define arm_lduw_code arm_lduw_code_x86_64
|
||||
#define arm_log_exception arm_log_exception_x86_64
|
||||
#define arm_phys_excp_target_el arm_phys_excp_target_el_x86_64
|
||||
#define arm_reg_read arm_reg_read_x86_64
|
||||
#define arm_reg_reset arm_reg_reset_x86_64
|
||||
#define arm_reg_write arm_reg_write_x86_64
|
||||
|
|
Loading…
Reference in a new issue