diff --git a/qemu/aarch64.h b/qemu/aarch64.h index 70f44343..1b33e379 100644 --- a/qemu/aarch64.h +++ b/qemu/aarch64.h @@ -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 diff --git a/qemu/aarch64eb.h b/qemu/aarch64eb.h index a3c33497..1a5814b1 100644 --- a/qemu/aarch64eb.h +++ b/qemu/aarch64eb.h @@ -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 diff --git a/qemu/arm.h b/qemu/arm.h index 21653c2d..a2d111bd 100644 --- a/qemu/arm.h +++ b/qemu/arm.h @@ -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 diff --git a/qemu/armeb.h b/qemu/armeb.h index 84f57e99..a0e8a14f 100644 --- a/qemu/armeb.h +++ b/qemu/armeb.h @@ -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 diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 5de624a8..c52d0664 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -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', diff --git a/qemu/m68k.h b/qemu/m68k.h index 4d4c0249..f4c94daa 100644 --- a/qemu/m68k.h +++ b/qemu/m68k.h @@ -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 diff --git a/qemu/mips.h b/qemu/mips.h index 0cf1fb5b..8d30d14f 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -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 diff --git a/qemu/mips64.h b/qemu/mips64.h index 7dc81fca..da300260 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -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 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 0b681ec2..6218b8d9 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -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 diff --git a/qemu/mipsel.h b/qemu/mipsel.h index 81a03b42..57f30b22 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -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 diff --git a/qemu/powerpc.h b/qemu/powerpc.h index fd73d67b..7824092a 100644 --- a/qemu/powerpc.h +++ b/qemu/powerpc.h @@ -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 diff --git a/qemu/sparc.h b/qemu/sparc.h index b1688cfc..e55500d0 100644 --- a/qemu/sparc.h +++ b/qemu/sparc.h @@ -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 diff --git a/qemu/sparc64.h b/qemu/sparc64.h index f728cccb..9befb684 100644 --- a/qemu/sparc64.h +++ b/qemu/sparc64.h @@ -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 diff --git a/qemu/target-arm/cpu.c b/qemu/target-arm/cpu.c index 34968da3..3361c076 100644 --- a/qemu/target-arm/cpu.c +++ b/qemu/target-arm/cpu.c @@ -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; diff --git a/qemu/target-arm/cpu.h b/qemu/target-arm/cpu.h index 14b480b1..3da0276e 100644 --- a/qemu/target-arm/cpu.h +++ b/qemu/target-arm/cpu.h @@ -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; diff --git a/qemu/target-arm/helper-a64.c b/qemu/target-arm/helper-a64.c index 059a941a..4006927b 100644 --- a/qemu/target-arm/helper-a64.c +++ b/qemu/target-arm/helper-a64.c @@ -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); diff --git a/qemu/target-arm/helper.c b/qemu/target-arm/helper.c index 393c7b66..bc7879ac 100644 --- a/qemu/target-arm/helper.c +++ b/qemu/target-arm/helper.c @@ -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)); diff --git a/qemu/x86_64.h b/qemu/x86_64.h index 708daeb1..eae59735 100644 --- a/qemu/x86_64.h +++ b/qemu/x86_64.h @@ -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