mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-13 02:29:46 +00:00
Further CPU cleanup
This commit is contained in:
parent
f4f035682c
commit
7835aec034
|
@ -277,6 +277,24 @@ enum FPSCR : uint32_t {
|
|||
FX = 0x80000000
|
||||
};
|
||||
|
||||
enum MSR : int {
|
||||
LE = 0x1, //little endian mode
|
||||
RI = 0x2,
|
||||
DR = 0x10,
|
||||
IR = 0x20,
|
||||
IP = 0x40,
|
||||
FE1 = 0x100,
|
||||
BE = 0x200,
|
||||
SE = 0x400,
|
||||
FE0 = 0x800,
|
||||
ME = 0x1000,
|
||||
FP = 0x2000,
|
||||
PR = 0x4000,
|
||||
EE = 0x8000, //external interrupt
|
||||
ILE = 0x10000,
|
||||
POW = 0x40000
|
||||
};
|
||||
|
||||
//for inf and nan checks
|
||||
enum FPOP : int {
|
||||
DIV = 0x12,
|
||||
|
|
|
@ -177,7 +177,7 @@ void ppc_fpu_off() {
|
|||
|
||||
void ppc_assert_int() {
|
||||
int_pin = true;
|
||||
if (ppc_state.msr & 0x8000) {
|
||||
if (ppc_state.msr & MSR::EE) {
|
||||
LOG_F(5, "CPU ExtIntHandler called");
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
|
||||
} else {
|
||||
|
@ -813,9 +813,9 @@ void ppc_cpu_init(MemCtrlBase* mem_ctrl, uint32_t cpu_version, uint64_t tb_freq)
|
|||
|
||||
if (is_601) {
|
||||
/* MPC601 sets MSR[ME] bit during hard reset / Power-On */
|
||||
ppc_state.msr = 0x1040;
|
||||
ppc_state.msr = (MSR::ME + MSR::IP);
|
||||
} else {
|
||||
ppc_state.msr = 0x40;
|
||||
ppc_state.msr = MSR::IP;
|
||||
ppc_state.spr[SPR::DEC] = 0xFFFFFFFFUL;
|
||||
}
|
||||
|
||||
|
|
|
@ -408,6 +408,8 @@ void dppc_interpreter::ppc_fnmsub() {
|
|||
ppc_dblresult64_d = (val_reg_a * val_reg_c);
|
||||
ppc_dblresult64_d -= val_reg_b;
|
||||
ppc_dblresult64_d = -(ppc_dblresult64_d);
|
||||
ppc_store_dfpresult_flt(reg_d);
|
||||
fpresult_update(ppc_dblresult64_d, rc_flag);
|
||||
|
||||
if (rc_flag)
|
||||
ppc_changecrf1(ppc_dblresult64_d);
|
||||
|
|
|
@ -95,7 +95,7 @@ static BATResult mpc601_block_address_translation(uint32_t la)
|
|||
unsigned key;
|
||||
|
||||
bool bat_hit = false;
|
||||
unsigned msr_pr = !!(ppc_state.msr & 0x4000);
|
||||
unsigned msr_pr = !!(ppc_state.msr & MSR::PR);
|
||||
|
||||
// I/O controller interface takes precedence over BAT in 601
|
||||
// Report BAT miss if T bit is set in the corresponding SR
|
||||
|
@ -139,7 +139,7 @@ static BATResult ppc_block_address_translation(uint32_t la)
|
|||
PPC_BAT_entry *bat_array;
|
||||
|
||||
bool bat_hit = false;
|
||||
unsigned msr_pr = !!(ppc_state.msr & 0x4000);
|
||||
unsigned msr_pr = !!(ppc_state.msr & MSR::PR);
|
||||
|
||||
bat_array = (type == BATType::IBAT) ? ibat_array : dbat_array;
|
||||
|
||||
|
@ -507,7 +507,7 @@ static TLBEntry* itlb2_refill(uint32_t guest_va)
|
|||
uint16_t flags = 0;
|
||||
|
||||
/* instruction address translation if enabled */
|
||||
if (ppc_state.msr & 0x20) {
|
||||
if (ppc_state.msr & MSR::IR) {
|
||||
// attempt block address translation first
|
||||
if (is_601) {
|
||||
bat_res = mpc601_block_address_translation(guest_va);
|
||||
|
@ -524,8 +524,7 @@ static TLBEntry* itlb2_refill(uint32_t guest_va)
|
|||
flags |= TLBFlags::TLBE_FROM_BAT; // tell the world we come from
|
||||
} else {
|
||||
// page address translation
|
||||
PATResult pat_res = page_address_translation(guest_va, true,
|
||||
!!(ppc_state.msr & 0x4000), 0);
|
||||
PATResult pat_res = page_address_translation(guest_va, true, !!(ppc_state.msr & MSR::PR), 0);
|
||||
phys_addr = pat_res.phys;
|
||||
flags = TLBFlags::TLBE_FROM_PAT; // tell the world we come from
|
||||
}
|
||||
|
@ -563,7 +562,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write)
|
|||
const uint32_t tag = guest_va & ~0xFFFUL;
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
// attempt block address translation first
|
||||
if (is_601) {
|
||||
bat_res = mpc601_block_address_translation(guest_va);
|
||||
|
@ -587,8 +586,7 @@ static TLBEntry* dtlb2_refill(uint32_t guest_va, int is_write)
|
|||
}
|
||||
} else {
|
||||
// page address translation
|
||||
PATResult pat_res = page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), is_write);
|
||||
PATResult pat_res = page_address_translation(guest_va, false, !!(ppc_state.msr & MSR::PR), is_write);
|
||||
phys_addr = pat_res.phys;
|
||||
flags = TLBFlags::TLBE_FROM_PAT; // tell the world we come from
|
||||
if (pat_res.prot <= 2 || pat_res.prot == 6) {
|
||||
|
@ -1154,8 +1152,7 @@ inline void mmu_write_vmem(uint32_t guest_va, T value)
|
|||
}
|
||||
if (!(tlb1_entry->flags & TLBFlags::PTE_SET_C)) {
|
||||
// perform full page address translation to update PTE.C bit
|
||||
page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
page_address_translation(guest_va, false, !!(ppc_state.msr & MSR::PR), true);
|
||||
tlb1_entry->flags |= TLBFlags::PTE_SET_C;
|
||||
|
||||
// don't forget to update the secondary TLB as well
|
||||
|
@ -1193,8 +1190,7 @@ inline void mmu_write_vmem(uint32_t guest_va, T value)
|
|||
|
||||
if (!(tlb2_entry->flags & TLBFlags::PTE_SET_C)) {
|
||||
// perform full page address translation to update PTE.C bit
|
||||
page_address_translation(guest_va, false,
|
||||
!!(ppc_state.msr & 0x4000), true);
|
||||
page_address_translation(guest_va, false, !!(ppc_state.msr & MSR::PR), true);
|
||||
tlb2_entry->flags |= TLBFlags::PTE_SET_C;
|
||||
}
|
||||
|
||||
|
@ -1594,7 +1590,7 @@ static uint32_t ppc_mmu_addr_translate(uint32_t la, int is_write)
|
|||
uint32_t pa; /* translated physical address */
|
||||
|
||||
bool bat_hit = false;
|
||||
unsigned msr_pr = !!(ppc_state.msr & 0x4000);
|
||||
unsigned msr_pr = !!(ppc_state.msr & MSR::PR);
|
||||
|
||||
// Format: %XY
|
||||
// X - supervisor access bit, Y - problem/user access bit
|
||||
|
@ -1655,7 +1651,7 @@ static void mem_write_unaligned(uint32_t addr, uint32_t value, uint32_t size) {
|
|||
// Because such accesses suffer a performance penalty, they will be
|
||||
// presumably very rare so don't care much about performance.
|
||||
for (int i = 0; i < size; shift -= 8, addr++, phys_addr++, i++) {
|
||||
if ((ppc_state.msr & 0x10) && (!i || !(addr & 0xFFF))) {
|
||||
if ((ppc_state.msr & MSR::DR) && (!i || !(addr & 0xFFF))) {
|
||||
phys_addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1664,7 +1660,7 @@ static void mem_write_unaligned(uint32_t addr, uint32_t value, uint32_t size) {
|
|||
}
|
||||
} else {
|
||||
// data address translation if enabled
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1758,7 +1754,7 @@ static uint32_t mem_grab_unaligned(uint32_t addr, uint32_t size) {
|
|||
// presumably very rare so don't care much about performance.
|
||||
for (int i = 0; i < size; addr++, phys_addr++, i++) {
|
||||
tlb_translate_addr(addr);
|
||||
if ((ppc_state.msr & 0x10) && (!i || !(addr & 0xFFF))) {
|
||||
if ((ppc_state.msr & MSR::DR) && (!i || !(addr & 0xFFF))) {
|
||||
phys_addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1769,7 +1765,7 @@ static uint32_t mem_grab_unaligned(uint32_t addr, uint32_t size) {
|
|||
|
||||
} else {
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1791,7 +1787,7 @@ void mem_write_byte(uint32_t addr, uint8_t value) {
|
|||
mmu_write_vmem<uint8_t>(addr, value);
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1807,7 +1803,7 @@ void mem_write_word(uint32_t addr, uint16_t value) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1823,7 +1819,7 @@ void mem_write_dword(uint32_t addr, uint32_t value) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1838,7 +1834,7 @@ void mem_write_qword(uint32_t addr, uint64_t value) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 1);
|
||||
}
|
||||
|
||||
|
@ -1850,7 +1846,7 @@ uint8_t mem_grab_byte(uint32_t addr) {
|
|||
tlb_translate_addr(addr);
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1865,7 +1861,7 @@ uint16_t mem_grab_word(uint32_t addr) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1880,7 +1876,7 @@ uint32_t mem_grab_dword(uint32_t addr) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1895,7 +1891,7 @@ uint64_t mem_grab_qword(uint32_t addr) {
|
|||
}
|
||||
|
||||
/* data address translation if enabled */
|
||||
if (ppc_state.msr & 0x10) {
|
||||
if (ppc_state.msr & MSR::DR) {
|
||||
addr = ppc_mmu_addr_translate(addr, 0);
|
||||
}
|
||||
|
||||
|
@ -1908,7 +1904,7 @@ static uint32_t mmu_instr_translation(uint32_t la)
|
|||
uint32_t pa; /* translated physical address */
|
||||
|
||||
bool bat_hit = false;
|
||||
unsigned msr_pr = !!(ppc_state.msr & 0x4000);
|
||||
unsigned msr_pr = !!(ppc_state.msr & MSR::PR);
|
||||
|
||||
// Format: %XY
|
||||
// X - supervisor access bit, Y - problem/user access bit
|
||||
|
@ -1956,7 +1952,7 @@ uint8_t* quickinstruction_translate(uint32_t addr) {
|
|||
#endif
|
||||
|
||||
/* perform instruction address translation if enabled */
|
||||
if (ppc_state.msr & 0x20) {
|
||||
if (ppc_state.msr & MSR::IR) {
|
||||
addr = mmu_instr_translation(addr);
|
||||
}
|
||||
|
||||
|
|
|
@ -774,53 +774,57 @@ void dppc_interpreter::ppc_mtsr() {
|
|||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if ((ppc_state.msr & 0x4000) == 0) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
reg_s = (ppc_cur_instruction >> 21) & 31;
|
||||
grab_sr = (ppc_cur_instruction >> 16) & 15;
|
||||
ppc_state.sr[grab_sr] = ppc_state.gpr[reg_s];
|
||||
mmu_pat_ctx_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mtsrin() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if ((ppc_state.msr & 0x4000) == 0) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
ppc_grab_regssb();
|
||||
grab_sr = ppc_result_b >> 28;
|
||||
ppc_state.sr[grab_sr] = ppc_result_d;
|
||||
mmu_pat_ctx_changed();
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mfsr() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if ((ppc_state.msr & 0x4000) == 0) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
reg_d = (ppc_cur_instruction >> 21) & 31;
|
||||
grab_sr = (ppc_cur_instruction >> 16) & 15;
|
||||
ppc_state.gpr[reg_d] = ppc_state.sr[grab_sr];
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mfsrin() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if ((ppc_state.msr & 0x4000) == 0) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
ppc_grab_regsdb();
|
||||
grab_sr = ppc_result_b >> 28;
|
||||
ppc_state.gpr[reg_d] = ppc_state.sr[grab_sr];
|
||||
}
|
||||
}
|
||||
|
||||
void dppc_interpreter::ppc_mfmsr() {
|
||||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if (ppc_state.msr & 0x4000) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
reg_d = (ppc_cur_instruction >> 21) & 31;
|
||||
|
@ -831,7 +835,7 @@ void dppc_interpreter::ppc_mtmsr() {
|
|||
#ifdef CPU_PROFILING
|
||||
num_supervisor_instrs++;
|
||||
#endif
|
||||
if (ppc_state.msr & 0x4000) {
|
||||
if (ppc_state.msr & MSR::PR) {
|
||||
ppc_exception_handler(Except_Type::EXC_PROGRAM, Exc_Cause::NOT_ALLOWED);
|
||||
}
|
||||
reg_s = (ppc_cur_instruction >> 21) & 31;
|
||||
|
@ -839,10 +843,10 @@ void dppc_interpreter::ppc_mtmsr() {
|
|||
|
||||
// generate External Interrupt Exception
|
||||
// if CPU interrupt line is asserted
|
||||
if (ppc_state.msr & 0x8000 && int_pin) {
|
||||
if (ppc_state.msr & MSR::EE && int_pin) {
|
||||
//LOG_F(WARNING, "MTMSR: CPU INT pending, generate CPU exception");
|
||||
ppc_exception_handler(Except_Type::EXC_EXT_INT, 0);
|
||||
} else if ((ppc_state.msr & 0x8000) && dec_exception_pending) {
|
||||
} else if ((ppc_state.msr & MSR::EE) && dec_exception_pending) {
|
||||
dec_exception_pending = false;
|
||||
//LOG_F(WARNING, "MTMSR: decrementer exception triggered");
|
||||
ppc_exception_handler(Except_Type::EXC_DECR, 0);
|
||||
|
@ -896,7 +900,7 @@ static void trigger_decrementer_exception() {
|
|||
decrementer_timer_id = 0;
|
||||
dec_wr_value = -1;
|
||||
dec_wr_timestamp = get_virt_time_ns();
|
||||
if (ppc_state.msr & 0x8000) {
|
||||
if (ppc_state.msr & MSR::EE) {
|
||||
dec_exception_pending = false;
|
||||
//LOG_F(WARNING, "decrementer exception triggered");
|
||||
ppc_exception_handler(Except_Type::EXC_DECR, 0);
|
||||
|
@ -1426,14 +1430,14 @@ void dppc_interpreter::ppc_rfi() {
|
|||
|
||||
// generate External Interrupt Exception
|
||||
// if CPU interrupt line is still asserted
|
||||
if (ppc_state.msr & 0x8000 && int_pin) {
|
||||
if (ppc_state.msr & MSR::EE && 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;
|
||||
}
|
||||
|
||||
if ((ppc_state.msr & 0x8000) && dec_exception_pending) {
|
||||
if ((ppc_state.msr & MSR::EE) && dec_exception_pending) {
|
||||
dec_exception_pending = false;
|
||||
//LOG_F(WARNING, "decrementer exception from rfi msr:0x%X", ppc_state.msr);
|
||||
uint32_t save_srr0 = ppc_state.spr[SPR::SRR0] & 0xFFFFFFFCUL;
|
||||
|
|
Loading…
Reference in New Issue
Block a user