void arm_cpu_do_interrupt(CPUState *cs) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; unsigned int new_el = env->exception.target_el; assert(!arm_feature(env, ARM_FEATURE_M)); arm_log_exception(cs->exception_index); qemu_log_mask(CPU_LOG_INT, "...from EL%d to EL%d\n", arm_current_el(env), new_el); if (qemu_loglevel_mask(CPU_LOG_INT) && !excp_is_internal(cs->exception_index)) { qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n", env->exception.syndrome >> ARM_EL_EC_SHIFT, env->exception.syndrome); } if (arm_is_psci_call(cpu, cs->exception_index)) { arm_handle_psci_call(cpu); qemu_log_mask(CPU_LOG_INT, "...handled as PSCI call\n"); return; } /* Semihosting semantics depend on the register width of the * code that caused the exception, not the target exception level, * so must be handled here. if (check_for_semihosting(cs)) { return; } assert(!excp_is_internal(cs->exception_index)); if (arm_el_is_aa64(env, new_el)) { arm_cpu_do_interrupt_aarch64(cs); } else { arm_cpu_do_interrupt_aarch32(cs); } arm_call_el_change_hook(cpu); if (!kvm_enabled()) { cs->interrupt_request |= CPU_INTERRUPT_EXITTB; } }