mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-02-22 13:29:49 +00:00
cpu/ppc: improve support for external interrupts.
Support generating of external interrupt exception in MTMSR and RFI when MSR[EE] is re-enabled and external interrupt still pending.
This commit is contained in:
parent
141a276c5b
commit
b38d00ce2d
@ -306,6 +306,7 @@ extern jmp_buf exc_env;
|
||||
extern bool grab_return;
|
||||
|
||||
extern bool power_on;
|
||||
extern bool int_pin;
|
||||
|
||||
extern bool is_601; // For PowerPC 601 Emulation
|
||||
extern bool is_altivec; // For Altivec Emulation
|
||||
@ -334,7 +335,8 @@ extern void ppc_mmu_init(uint32_t cpu_version);
|
||||
|
||||
void ppc_illegalop();
|
||||
void ppc_fpu_off();
|
||||
void ppc_ext_int();
|
||||
void ppc_assert_int();
|
||||
void ppc_release_int();
|
||||
|
||||
//void ppc_opcode4();
|
||||
void ppc_opcode16();
|
||||
|
@ -43,8 +43,8 @@ bool power_on = 1;
|
||||
|
||||
SetPRS ppc_state;
|
||||
|
||||
bool rc_flag = 0; // Record flag
|
||||
bool oe_flag = 0; // Overflow flag
|
||||
bool rc_flag = 0; // Record flag
|
||||
bool oe_flag = 0; // Overflow flag
|
||||
|
||||
bool grab_return;
|
||||
bool grab_breakpoint;
|
||||
@ -53,7 +53,8 @@ uint32_t ppc_cur_instruction; // Current instruction for the PPC
|
||||
uint32_t ppc_effective_address;
|
||||
uint32_t ppc_next_instruction_address; // Used for branching, setting up the NIA
|
||||
|
||||
unsigned exec_flags;
|
||||
unsigned exec_flags; // execution control flags
|
||||
bool int_pin = false; // interrupt request pin state: true - asserted
|
||||
|
||||
/* copy of local variable bb_start_la. Need for correct
|
||||
calculation of CPU cycles after setjmp that clobbers
|
||||
@ -170,12 +171,20 @@ void ppc_fpu_off() {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::FPU_OFF);
|
||||
}
|
||||
|
||||
void ppc_ext_int() {
|
||||
void ppc_assert_int() {
|
||||
int_pin = true;
|
||||
if (ppc_state.msr & 0x8000) {
|
||||
LOG_F(5, "CPU ExtIntHandler called");
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
|
||||
} else {
|
||||
LOG_F(5, "CPU IRQ ignored!");
|
||||
}
|
||||
}
|
||||
|
||||
void ppc_release_int() {
|
||||
int_pin = false;
|
||||
}
|
||||
|
||||
/** Opcode decoding functions. */
|
||||
|
||||
void ppc_opcode16() {
|
||||
@ -395,6 +404,9 @@ void ppc_exec_single()
|
||||
|
||||
mmu_translate_imem(ppc_state.pc);
|
||||
ppc_main_opcode();
|
||||
g_icycles++;
|
||||
process_events();
|
||||
|
||||
if (exec_flags) {
|
||||
if (exec_flags & EXEF_TIMER) {
|
||||
ppc_state.pc += 4;
|
||||
@ -405,7 +417,6 @@ void ppc_exec_single()
|
||||
} else {
|
||||
ppc_state.pc += 4;
|
||||
}
|
||||
g_icycles++;
|
||||
}
|
||||
|
||||
/** Execute PPC code until goal_addr is reached. */
|
||||
|
@ -844,7 +844,15 @@ void dppc_interpreter::ppc_mtmsr() {
|
||||
}
|
||||
reg_s = (ppc_cur_instruction >> 21) & 31;
|
||||
ppc_state.msr = ppc_state.gpr[reg_s];
|
||||
mmu_change_mode();
|
||||
|
||||
// generate External Interrupt Exception
|
||||
// if CPU interrupt line is asserted
|
||||
if (ppc_state.msr & 0x8000 && int_pin) {
|
||||
LOG_F(WARNING, "MTMSR: CPU INT pending, generate CPU exception");
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
|
||||
} else {
|
||||
mmu_change_mode();
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t calc_rtcl_value()
|
||||
@ -1359,6 +1367,16 @@ void dppc_interpreter::ppc_rfi() {
|
||||
uint32_t new_srr1_val = (ppc_state.spr[SPR::SRR1] & 0x87C0FF73UL);
|
||||
uint32_t new_msr_val = (ppc_state.msr & ~(0x87C0FF73UL));
|
||||
ppc_state.msr = (new_msr_val | new_srr1_val) & 0xFFFBFFFFUL;
|
||||
|
||||
// generate External Interrupt Exception
|
||||
// if CPU interrupt line is still asserted
|
||||
if (ppc_state.msr & 0x8000 && int_pin) {
|
||||
uint32_t save_srr0 = ppc_state.spr[SPR::SRR0] & 0xFFFFFFFCUL;
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
|
||||
ppc_state.spr[SPR::SRR0] = save_srr0;
|
||||
return;
|
||||
}
|
||||
|
||||
ppc_next_instruction_address = ppc_state.spr[SPR::SRR0] & 0xFFFFFFFCUL;
|
||||
|
||||
do_ctx_sync(); // RFI is context synchronizing
|
||||
|
Loading…
x
Reference in New Issue
Block a user