mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
cpu: Replace do_interrupt() by CPUClass::do_interrupt method
This removes a global per-target function and thus takes us one step closer to compiling multiple targets into one executable. It will also allow to override the interrupt handling for certain CPU families. Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
+20
-16
@@ -198,6 +198,10 @@ volatile sig_atomic_t exit_request;
|
||||
int cpu_exec(CPUArchState *env)
|
||||
{
|
||||
CPUState *cpu = ENV_GET_CPU(env);
|
||||
#if !(defined(CONFIG_USER_ONLY) && \
|
||||
(defined(TARGET_M68K) || defined(TARGET_PPC) || defined(TARGET_S390X)))
|
||||
CPUClass *cc = CPU_GET_CLASS(cpu);
|
||||
#endif
|
||||
int ret, interrupt_request;
|
||||
TranslationBlock *tb;
|
||||
uint8_t *tc_ptr;
|
||||
@@ -265,12 +269,12 @@ int cpu_exec(CPUArchState *env)
|
||||
which will be handled outside the cpu execution
|
||||
loop */
|
||||
#if defined(TARGET_I386)
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
#endif
|
||||
ret = env->exception_index;
|
||||
break;
|
||||
#else
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
env->exception_index = -1;
|
||||
#endif
|
||||
}
|
||||
@@ -380,7 +384,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if ((interrupt_request & CPU_INTERRUPT_HARD)
|
||||
&& (env->ie & IE_IE)) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_MICROBLAZE)
|
||||
@@ -389,7 +393,7 @@ int cpu_exec(CPUArchState *env)
|
||||
&& !(env->sregs[SR_MSR] & (MSR_EIP | MSR_BIP))
|
||||
&& !(env->iflags & (D_FLAG | IMM_FLAG))) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_MIPS)
|
||||
@@ -398,7 +402,7 @@ int cpu_exec(CPUArchState *env)
|
||||
/* Raise it */
|
||||
env->exception_index = EXCP_EXT_INTERRUPT;
|
||||
env->error_code = 0;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_OPENRISC)
|
||||
@@ -414,7 +418,7 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
if (idx >= 0) {
|
||||
env->exception_index = idx;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
}
|
||||
@@ -429,7 +433,7 @@ int cpu_exec(CPUArchState *env)
|
||||
cpu_pil_allowed(env, pil)) ||
|
||||
type != TT_EXTINT) {
|
||||
env->exception_index = env->interrupt_index;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
}
|
||||
@@ -438,7 +442,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if (interrupt_request & CPU_INTERRUPT_FIQ
|
||||
&& !(env->uncached_cpsr & CPSR_F)) {
|
||||
env->exception_index = EXCP_FIQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
/* ARMv7-M interrupt return works by loading a magic value
|
||||
@@ -454,19 +458,19 @@ int cpu_exec(CPUArchState *env)
|
||||
&& ((IS_M(env) && env->regs[15] < 0xfffffff0)
|
||||
|| !(env->uncached_cpsr & CPSR_I))) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_UNICORE32)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD
|
||||
&& !(env->uncached_asr & ASR_I)) {
|
||||
env->exception_index = UC32_EXCP_INTR;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_SH4)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_ALPHA)
|
||||
@@ -497,7 +501,7 @@ int cpu_exec(CPUArchState *env)
|
||||
if (idx >= 0) {
|
||||
env->exception_index = idx;
|
||||
env->error_code = 0;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
}
|
||||
@@ -506,7 +510,7 @@ int cpu_exec(CPUArchState *env)
|
||||
&& (env->pregs[PR_CCS] & I_FLAG)
|
||||
&& !env->locked_irq) {
|
||||
env->exception_index = EXCP_IRQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
if (interrupt_request & CPU_INTERRUPT_NMI) {
|
||||
@@ -518,7 +522,7 @@ int cpu_exec(CPUArchState *env)
|
||||
}
|
||||
if ((env->pregs[PR_CCS] & m_flag_archval)) {
|
||||
env->exception_index = EXCP_NMI;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
}
|
||||
@@ -538,13 +542,13 @@ int cpu_exec(CPUArchState *env)
|
||||
#elif defined(TARGET_S390X) && !defined(CONFIG_USER_ONLY)
|
||||
if ((interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||
(env->psw.mask & PSW_MASK_EXT)) {
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#elif defined(TARGET_XTENSA)
|
||||
if (interrupt_request & CPU_INTERRUPT_HARD) {
|
||||
env->exception_index = EXC_IRQ;
|
||||
do_interrupt(env);
|
||||
cc->do_interrupt(cpu);
|
||||
next_tb = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,7 @@ typedef struct CPUState CPUState;
|
||||
* @class_by_name: Callback to map -cpu command line model name to an
|
||||
* instantiatable CPU type.
|
||||
* @reset: Callback to reset the #CPUState to its initial state.
|
||||
* @do_interrupt: Callback for interrupt handling.
|
||||
* @vmsd: State description for migration.
|
||||
*
|
||||
* Represents a CPU family or model.
|
||||
@@ -56,6 +57,7 @@ typedef struct CPUClass {
|
||||
ObjectClass *(*class_by_name)(const char *cpu_model);
|
||||
|
||||
void (*reset)(CPUState *cpu);
|
||||
void (*do_interrupt)(CPUState *cpu);
|
||||
|
||||
const struct VMStateDescription *vmsd;
|
||||
} CPUClass;
|
||||
|
||||
@@ -74,4 +74,6 @@ static inline AlphaCPU *alpha_env_get_cpu(CPUAlphaState *env)
|
||||
|
||||
#define ENV_OFFSET offsetof(AlphaCPU, env)
|
||||
|
||||
void alpha_cpu_do_interrupt(CPUState *cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -263,6 +263,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
|
||||
dc->realize = alpha_cpu_realizefn;
|
||||
|
||||
cc->class_by_name = alpha_cpu_class_by_name;
|
||||
cc->do_interrupt = alpha_cpu_do_interrupt;
|
||||
}
|
||||
|
||||
static const TypeInfo alpha_cpu_type_info = {
|
||||
|
||||
@@ -449,7 +449,6 @@ int cpu_alpha_signal_handler(int host_signum, void *pinfo,
|
||||
int cpu_alpha_handle_mmu_fault (CPUAlphaState *env, uint64_t address, int rw,
|
||||
int mmu_idx);
|
||||
#define cpu_handle_mmu_fault cpu_alpha_handle_mmu_fault
|
||||
void do_interrupt (CPUAlphaState *env);
|
||||
void do_restore_state(CPUAlphaState *, uintptr_t retaddr);
|
||||
void QEMU_NORETURN dynamic_excp(CPUAlphaState *, uintptr_t, int, int);
|
||||
void QEMU_NORETURN arith_excp(CPUAlphaState *, uintptr_t, int, uint64_t);
|
||||
|
||||
@@ -345,8 +345,10 @@ int cpu_alpha_handle_mmu_fault(CPUAlphaState *env, target_ulong addr, int rw,
|
||||
}
|
||||
#endif /* USER_ONLY */
|
||||
|
||||
void do_interrupt (CPUAlphaState *env)
|
||||
void alpha_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
AlphaCPU *cpu = ALPHA_CPU(cs);
|
||||
CPUAlphaState *env = &cpu->env;
|
||||
int i = env->exception_index;
|
||||
|
||||
if (qemu_loglevel_mask(CPU_LOG_INT)) {
|
||||
|
||||
@@ -113,4 +113,6 @@ static inline ARMCPU *arm_env_get_cpu(CPUARMState *env)
|
||||
|
||||
void register_cp_regs_for_features(ARMCPU *cpu);
|
||||
|
||||
void arm_cpu_do_interrupt(CPUState *cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -802,6 +802,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
|
||||
cc->reset = arm_cpu_reset;
|
||||
|
||||
cc->class_by_name = arm_cpu_class_by_name;
|
||||
cc->do_interrupt = arm_cpu_do_interrupt;
|
||||
}
|
||||
|
||||
static void cpu_register(const ARMCPUInfo *info)
|
||||
|
||||
@@ -236,7 +236,6 @@ ARMCPU *cpu_arm_init(const char *cpu_model);
|
||||
void arm_translate_init(void);
|
||||
void arm_cpu_register_gdb_regs_for_features(ARMCPU *cpu);
|
||||
int cpu_arm_exec(CPUARMState *s);
|
||||
void do_interrupt(CPUARMState *);
|
||||
int bank_number(int mode);
|
||||
void switch_mode(CPUARMState *, int);
|
||||
uint32_t do_arm_semihosting(CPUARMState *env);
|
||||
|
||||
+7
-4
@@ -1567,8 +1567,11 @@ uint32_t HELPER(rbit)(uint32_t x)
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
void do_interrupt (CPUARMState *env)
|
||||
void arm_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
|
||||
env->exception_index = -1;
|
||||
}
|
||||
|
||||
@@ -1799,9 +1802,10 @@ static void do_interrupt_v7m(CPUARMState *env)
|
||||
}
|
||||
|
||||
/* Handle a CPU exception. */
|
||||
void do_interrupt(CPUARMState *env)
|
||||
void arm_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
CPUState *cs;
|
||||
ARMCPU *cpu = ARM_CPU(cs);
|
||||
CPUARMState *env = &cpu->env;
|
||||
uint32_t addr;
|
||||
uint32_t mask;
|
||||
int new_mode;
|
||||
@@ -1908,7 +1912,6 @@ void do_interrupt(CPUARMState *env)
|
||||
}
|
||||
env->regs[14] = env->regs[15] + offset;
|
||||
env->regs[15] = addr;
|
||||
cs = CPU(arm_env_get_cpu(env));
|
||||
cs->interrupt_request |= CPU_INTERRUPT_EXITTB;
|
||||
}
|
||||
|
||||
|
||||
@@ -73,4 +73,6 @@ static inline CRISCPU *cris_env_get_cpu(CPUCRISState *env)
|
||||
|
||||
#define ENV_OFFSET offsetof(CRISCPU, env)
|
||||
|
||||
void cris_cpu_do_interrupt(CPUState *cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -243,6 +243,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
|
||||
cc->reset = cris_cpu_reset;
|
||||
|
||||
cc->class_by_name = cris_cpu_class_by_name;
|
||||
cc->do_interrupt = cris_cpu_do_interrupt;
|
||||
}
|
||||
|
||||
static const TypeInfo cris_cpu_type_info = {
|
||||
|
||||
@@ -175,7 +175,6 @@ typedef struct CPUCRISState {
|
||||
|
||||
CRISCPU *cpu_cris_init(const char *cpu_model);
|
||||
int cpu_cris_exec(CPUCRISState *s);
|
||||
void do_interrupt(CPUCRISState *env);
|
||||
/* you can call this signal handler from your SIGBUS and SIGSEGV
|
||||
signal handlers to inform the virtual CPU of exceptions. non zero
|
||||
is returned if the signal was handled by the virtual CPU. */
|
||||
|
||||
@@ -36,8 +36,11 @@
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
|
||||
void do_interrupt(CPUCRISState *env)
|
||||
void cris_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
CRISCPU *cpu = CRIS_CPU(cs);
|
||||
CPUCRISState *env = &cpu->env;
|
||||
|
||||
env->exception_index = -1;
|
||||
env->pregs[PR_ERP] = env->pc;
|
||||
}
|
||||
@@ -162,9 +165,10 @@ static void do_interruptv10(CPUCRISState *env)
|
||||
env->pregs[PR_ERP]);
|
||||
}
|
||||
|
||||
void do_interrupt(CPUCRISState *env)
|
||||
void cris_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
D(CPUState *cs = CPU(cris_env_get_cpu(env)));
|
||||
CRISCPU *cpu = CRIS_CPU(cs);
|
||||
CPUCRISState *env = &cpu->env;
|
||||
int ex_vec = -1;
|
||||
|
||||
if (env->pregs[PR_VR] < 32) {
|
||||
|
||||
@@ -80,4 +80,10 @@ static inline X86CPU *x86_env_get_cpu(CPUX86State *env)
|
||||
extern const struct VMStateDescription vmstate_x86_cpu;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* x86_cpu_do_interrupt:
|
||||
* @cpu: vCPU the interrupt is to be handled by.
|
||||
*/
|
||||
void x86_cpu_do_interrupt(CPUState *cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2251,6 +2251,7 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
|
||||
xcc->parent_reset = cc->reset;
|
||||
cc->reset = x86_cpu_reset;
|
||||
|
||||
cc->do_interrupt = x86_cpu_do_interrupt;
|
||||
cpu_class_set_vmsd(cc, &vmstate_x86_cpu);
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -1252,8 +1252,7 @@ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
|
||||
uint64_t param);
|
||||
void cpu_vmexit(CPUX86State *nenv, uint32_t exit_code, uint64_t exit_info_1);
|
||||
|
||||
/* op_helper.c */
|
||||
void do_interrupt(CPUX86State *env);
|
||||
/* seg_helper.c */
|
||||
void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
|
||||
|
||||
void do_smm_enter(CPUX86State *env1);
|
||||
|
||||
@@ -1231,8 +1231,11 @@ static void do_interrupt_all(CPUX86State *env, int intno, int is_int,
|
||||
#endif
|
||||
}
|
||||
|
||||
void do_interrupt(CPUX86State *env)
|
||||
void x86_cpu_do_interrupt(CPUState *cs)
|
||||
{
|
||||
X86CPU *cpu = X86_CPU(cs);
|
||||
CPUX86State *env = &cpu->env;
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
/* if user mode only, we simulate a fake exception
|
||||
which will be handled outside the cpu execution
|
||||
|
||||
@@ -71,4 +71,6 @@ static inline LM32CPU *lm32_env_get_cpu(CPULM32State *env)
|
||||
|
||||
#define ENV_OFFSET offsetof(LM32CPU, env)
|
||||
|
||||
void lm32_cpu_do_interrupt(CPUState *cpu);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -83,6 +83,8 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
|
||||
|
||||
lcc->parent_reset = cc->reset;
|
||||
cc->reset = lm32_cpu_reset;
|
||||
|
||||
cc->do_interrupt = lm32_cpu_do_interrupt;
|
||||
}
|
||||
|
||||
static const TypeInfo lm32_cpu_type_info = {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user