diff --git a/cpu/ppc/ppcemu.h b/cpu/ppc/ppcemu.h index d32354a..2105aa1 100644 --- a/cpu/ppc/ppcemu.h +++ b/cpu/ppc/ppcemu.h @@ -8,6 +8,7 @@ #ifndef PPCEMU_H #define PPCEMU_H +#include #include "devices/memctrlbase.h" //Uncomment this to help debug the emulator further @@ -160,15 +161,33 @@ extern int32_t simm_rev_endian16(int32_t insert_int); extern uint32_t rev_endian32(uint32_t insert_int); extern uint64_t rev_endian64(uint64_t insert_int); -/* The precise reason for the termination of a basic block. */ -enum class BB_end_reason { +/* The precise end of a basic block. */ +enum class BB_end_kind { + BB_NONE = 0, /* no basic block end is reached */ BB_BRANCH = 1, /* a branch instruction is encountered */ BB_EXCEPTION, /* an exception is occured */ BB_RFI /* the rfi instruction is encountered */ }; -extern bool bb_end; -extern BB_end_reason bb_kind; +/** PowerPC exception types. */ +enum class Except_Type { + EXC_SYSTEM_RESET = 1, + EXC_MACHINE_CHECK, + EXC_DSI, + EXC_ISI, + EXC_EXT_INT, + EXC_ALIGNMENT, + EXC_PROGRAM, + EXC_NO_FPU, + EXC_DECR, + EXC_SYSCALL = 12, + EXC_TRACE = 13 +}; + +//extern bool bb_end; +extern BB_end_kind bb_kind; + +extern jmp_buf exc_env; extern bool grab_branch; extern bool grab_exception; @@ -241,7 +260,8 @@ void ppc_changecrf0(uint32_t set_result); void ppc_fp_changecrf1(); void ppc_tbr_update(); -void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args); +[[noreturn]] void ppc_exception_handler(Except_Type exception_type, + uint32_t srr1_bits); //MEMORY DECLARATIONS extern MemCtrlBase *mem_ctrl_instance; diff --git a/cpu/ppc/ppcexceptions.cpp b/cpu/ppc/ppcexceptions.cpp new file mode 100644 index 0000000..cd985f3 --- /dev/null +++ b/cpu/ppc/ppcexceptions.cpp @@ -0,0 +1,90 @@ +/** @file Handling of low-level PPC exceptions. */ + +#include +#include "ppcemu.h" + +jmp_buf exc_env; /* Global exception environment. */ + +[[noreturn]] void ppc_exception_handler(Except_Type exception_type, + uint32_t srr1_bits) +{ + grab_exception = true; + bb_kind = BB_end_kind::BB_EXCEPTION; + + switch(exception_type) { + case Except_Type::EXC_SYSTEM_RESET: + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0100; + break; + + case Except_Type::EXC_MACHINE_CHECK: + if (!(ppc_state.ppc_msr & 0x1000)) { + /* TODO: handle internal checkstop */ + } + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0200; + break; + + case Except_Type::EXC_DSI: + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0300; + break; + + case Except_Type::EXC_ISI: + ppc_state.ppc_spr[26] = ppc_next_instruction_address; + ppc_next_instruction_address = 0x0400; + break; + + case Except_Type::EXC_EXT_INT: + ppc_state.ppc_spr[26] = ppc_next_instruction_address; + ppc_next_instruction_address = 0x0500; + break; + + case Except_Type::EXC_ALIGNMENT: + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0600; + break; + + case Except_Type::EXC_PROGRAM: + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0700; + break; + + case Except_Type::EXC_NO_FPU: + ppc_state.ppc_spr[26] = ppc_cur_instruction & 0xFFFFFFFC; + ppc_next_instruction_address = 0x0800; + break; + + case Except_Type::EXC_DECR: + ppc_state.ppc_spr[26] = (ppc_cur_instruction & 0xFFFFFFFC) + 4; + ppc_next_instruction_address = 0x0900; + break; + + case Except_Type::EXC_SYSCALL: + ppc_state.ppc_spr[26] = (ppc_cur_instruction & 0xFFFFFFFC) + 4; + ppc_next_instruction_address = 0x0C00; + break; + + case Except_Type::EXC_TRACE: + ppc_state.ppc_spr[26] = (ppc_cur_instruction & 0xFFFFFFFC) + 4; + ppc_next_instruction_address = 0x0D00; + break; + + default: + //printf("Unknown exception occured: %X\n", exception_type); + //exit(-1); + break; + } + + ppc_state.ppc_spr[27] = (ppc_state.ppc_msr & 0x0000FF73) | srr1_bits; + ppc_state.ppc_msr &= 0xFFFB1041; + /* copy MSR[ILE] to MSR[LE] */ + ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFFFFFE) | + ((ppc_state.ppc_msr >> 16) & 1); + + if (ppc_state.ppc_msr & 0x40) { + ppc_next_instruction_address |= 0xFFF00000; + } + + longjmp(exc_env, 2); /* return to the main execution loop. */ +} diff --git a/cpu/ppc/ppcexec.cpp b/cpu/ppc/ppcexec.cpp index 4cb4a9b..e597714 100644 --- a/cpu/ppc/ppcexec.cpp +++ b/cpu/ppc/ppcexec.cpp @@ -7,14 +7,14 @@ #include #include +#include #include "ppcemu.h" #include "ppcmmu.h" bool power_on = 1; -bool bb_end = 0; /* "true" means a basic block was terminated */ -BB_end_reason bb_kind; /* the reason for the termination of a basic block */ +BB_end_kind bb_kind; /* basic block end */ uint64_t timebase_counter; /* internal timebase counter */ @@ -395,7 +395,6 @@ void ppc_illegalop(){ uint32_t grab_it = (uint32_t) illegal_code; printf("Illegal opcode reported: %d Report this! \n", grab_it); exit(-1); - //ppc_exception_handler(0x0700, 0x80000); } void ppc_illegalsubop31(){ @@ -430,7 +429,7 @@ void ppc_opcode19(){ } else{ std::cout << "ILLEGAL SUBOPCODE: " << subop_grab << std::endl; - ppc_exception_handler(0x0700, 0x80000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); } #else SubOpcode19Grabber[subop_grab](); @@ -447,7 +446,7 @@ void ppc_opcode31(){ } else{ std::cout << "ILLEGAL SUBOPCODE: " << subop_grab << std::endl; - ppc_exception_handler(0x0700, 0x80000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); } #else SubOpcode31Grabber[subop_grab](); @@ -464,7 +463,7 @@ void ppc_opcode59(){ } else{ std::cout << "ILLEGAL SUBOPCODE: " << subop_grab << std::endl; - ppc_exception_handler(0x0700, 0x80000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); } #else SubOpcode59Grabber[subop_grab](); @@ -481,7 +480,7 @@ void ppc_opcode63(){ } else{ std::cout << "ILLEGAL SUBOPCODE: " << subop_grab << std::endl; - ppc_exception_handler(0x0700, 0x80000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x80000); } #else SubOpcode63Grabber[subop_grab](); @@ -553,7 +552,18 @@ void ppc_exec() /* start new basic block */ bb_start_la = ppc_state.ppc_pc; - bb_end = false; + bb_kind = BB_end_kind::BB_NONE; + + if (setjmp(exc_env)) { + /* reaching here means we got a low-level exception */ + timebase_counter += (ppc_state.ppc_pc - bb_start_la) >> 2; + bb_start_la = ppc_next_instruction_address; + pc_real = quickinstruction_translate(bb_start_la); + page_start = bb_start_la & 0xFFFFF000; + ppc_state.ppc_pc = bb_start_la; + bb_kind = BB_end_kind::BB_NONE; + goto again; + } /* initial MMU translation for the current code page. */ pc_real = quickinstruction_translate(bb_start_la); @@ -561,9 +571,10 @@ void ppc_exec() /* set current code page limits */ page_start = bb_start_la & 0xFFFFF000; +again: while (power_on) { ppc_main_opcode(); - if (bb_end) { + if (bb_kind != BB_end_kind::BB_NONE) { timebase_counter += (ppc_state.ppc_pc - bb_start_la) >> 2; bb_start_la = ppc_next_instruction_address; if ((ppc_next_instruction_address & 0xFFFFF000) != page_start) { @@ -574,7 +585,7 @@ void ppc_exec() ppc_set_cur_instruction(pc_real); } ppc_state.ppc_pc = bb_start_la; - bb_end = false; + bb_kind = BB_end_kind::BB_NONE; } else { ppc_state.ppc_pc += 4; pc_real += 4; @@ -609,11 +620,19 @@ void ppc_exec_single() #else void ppc_exec_single() { + if (setjmp(exc_env)) { + /* reaching here means we got a low-level exception */ + timebase_counter += 1; + ppc_state.ppc_pc = ppc_next_instruction_address; + bb_kind = BB_end_kind::BB_NONE; + return; + } + quickinstruction_translate(ppc_state.ppc_pc); ppc_main_opcode(); - if (bb_end) { + if (bb_kind != BB_end_kind::BB_NONE) { ppc_state.ppc_pc = ppc_next_instruction_address; - bb_end = false; + bb_kind = BB_end_kind::BB_NONE; } else { ppc_state.ppc_pc += 4; } @@ -654,7 +673,18 @@ void ppc_exec_until(uint32_t goal_addr) /* start new basic block */ bb_start_la = ppc_state.ppc_pc; - bb_end = false; + bb_kind = BB_end_kind::BB_NONE; + + if (setjmp(exc_env)) { + /* reaching here means we got a low-level exception */ + timebase_counter += (ppc_state.ppc_pc - bb_start_la) >> 2; + bb_start_la = ppc_next_instruction_address; + pc_real = quickinstruction_translate(bb_start_la); + page_start = bb_start_la & 0xFFFFF000; + ppc_state.ppc_pc = bb_start_la; + bb_kind = BB_end_kind::BB_NONE; + goto again; + } /* initial MMU translation for the current code page. */ pc_real = quickinstruction_translate(bb_start_la); @@ -662,9 +692,10 @@ void ppc_exec_until(uint32_t goal_addr) /* set current code page limits */ page_start = bb_start_la & 0xFFFFF000; +again: while (ppc_state.ppc_pc != goal_addr) { ppc_main_opcode(); - if (bb_end) { + if (bb_kind != BB_end_kind::BB_NONE) { timebase_counter += (ppc_state.ppc_pc - bb_start_la) >> 2; bb_start_la = ppc_next_instruction_address; if ((ppc_next_instruction_address & 0xFFFFF000) != page_start) { @@ -675,7 +706,7 @@ void ppc_exec_until(uint32_t goal_addr) ppc_set_cur_instruction(pc_real); } ppc_state.ppc_pc = bb_start_la; - bb_end = false; + bb_kind = BB_end_kind::BB_NONE; } else { ppc_state.ppc_pc += 4; pc_real += 4; diff --git a/cpu/ppc/ppcmmu.cpp b/cpu/ppc/ppcmmu.cpp index 5d8a6e8..dd24d4a 100644 --- a/cpu/ppc/ppcmmu.cpp +++ b/cpu/ppc/ppcmmu.cpp @@ -209,7 +209,7 @@ static bool search_pteg(uint8_t *pteg_addr, uint8_t **ret_pte_addr, } static uint32_t page_address_translate(uint32_t la, bool is_instr_fetch, - unsigned msr_pr, bool is_write) + unsigned msr_pr, int is_write) { uint32_t sr_val, page_index, pteg_hash1, vsid, pte_word2; unsigned key, pp; @@ -223,7 +223,7 @@ static uint32_t page_address_translate(uint32_t la, bool is_instr_fetch, /* instruction fetch from a no-execute segment will cause ISI exception */ if ((sr_val & 0x10000000) && is_instr_fetch) { - ppc_exception_handler(0x400, 0); // FIXME: proper exception handling! + ppc_exception_handler(Except_Type::EXC_ISI, 0x10000000); } page_index = (la >> 12) & 0xFFFF; @@ -233,9 +233,11 @@ static uint32_t page_address_translate(uint32_t la, bool is_instr_fetch, if (!search_pteg(calc_pteg_addr(pteg_hash1), &pte_addr, vsid, page_index, 0)) { if (!search_pteg(calc_pteg_addr(~pteg_hash1), &pte_addr, vsid, page_index, 1)) { if (is_instr_fetch) { - ppc_exception_handler(0x400, 0); + ppc_exception_handler(Except_Type::EXC_ISI, 0x40000000); } else { - ppc_exception_handler(0x300, 0); + ppc_state.ppc_spr[18] = 0x40000000 | (is_write << 25); + ppc_state.ppc_spr[19] = la; + ppc_exception_handler(Except_Type::EXC_DSI, 0); } } } @@ -253,9 +255,11 @@ static uint32_t page_address_translate(uint32_t la, bool is_instr_fetch, // write access with PP = %11 if ((key && (!pp || (pp == 1 && is_write))) || (pp == 3 && is_write)) { if (is_instr_fetch) { - ppc_exception_handler(0x400, 0); + ppc_exception_handler(Except_Type::EXC_ISI, 0x08000000); } else { - ppc_exception_handler(0x300, 0); + ppc_state.ppc_spr[18] = 0x08000000 | (is_write << 25); + ppc_state.ppc_spr[19] = la; + ppc_exception_handler(Except_Type::EXC_DSI, 0); } } @@ -271,7 +275,7 @@ static uint32_t page_address_translate(uint32_t la, bool is_instr_fetch, } /** PowerPC-style MMU instruction address translation. */ -uint32_t ppc_mmu_instr_translate(uint32_t la) +static uint32_t ppc_mmu_instr_translate(uint32_t la) { uint32_t pa; /* translated physical address */ @@ -299,14 +303,14 @@ uint32_t ppc_mmu_instr_translate(uint32_t la) /* page address translation */ if (!bat_hit) { - pa = page_address_translate(la, true, msr_pr, false); + pa = page_address_translate(la, true, msr_pr, 0); } return pa; } /** PowerPC-style MMU data address translation. */ -uint32_t ppc_mmu_addr_translate(uint32_t la, bool is_write) +static uint32_t ppc_mmu_addr_translate(uint32_t la, int is_write) { uint32_t pa; /* translated physical address */ @@ -349,7 +353,7 @@ void address_quickinsert_translate(uint32_t value, uint32_t addr, uint8_t num_by { /* data address translation if enabled */ if (ppc_state.ppc_msr & 0x10) { - addr = ppc_mmu_addr_translate(addr, true); + addr = ppc_mmu_addr_translate(addr, 1); } if (addr >= write_last_pa_start && addr <= write_last_pa_end) { @@ -383,7 +387,7 @@ void address_quickgrab_translate(uint32_t addr, uint8_t num_bytes) { /* data address translation if enabled */ if (ppc_state.ppc_msr & 0x10) { - addr = ppc_mmu_addr_translate(addr, false); + addr = ppc_mmu_addr_translate(addr, 0); } if (addr >= read_last_pa_start && addr <= read_last_pa_end) { diff --git a/cpu/ppc/ppcopcodes.cpp b/cpu/ppc/ppcopcodes.cpp index 63af671..8197223 100644 --- a/cpu/ppc/ppcopcodes.cpp +++ b/cpu/ppc/ppcopcodes.cpp @@ -1273,17 +1273,19 @@ void ppc_mfsrin(){ } void ppc_mfmsr(){ - if ((ppc_state.ppc_msr & 0x4000) == 0){ - reg_d = (ppc_cur_instruction >> 21) & 31; - ppc_state.ppc_gpr[reg_d] = ppc_state.ppc_msr; + if (ppc_state.ppc_msr & 0x4000) { + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000); } + reg_d = (ppc_cur_instruction >> 21) & 31; + ppc_state.ppc_gpr[reg_d] = ppc_state.ppc_msr; } void ppc_mtmsr(){ - //if ((ppc_state.ppc_msr && 0x4000) == 0){ - reg_s = (ppc_cur_instruction >> 21) & 31; - ppc_state.ppc_msr = ppc_state.ppc_gpr[reg_s]; - //} + if (ppc_state.ppc_msr & 0x4000) { + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x00040000); + } + reg_s = (ppc_cur_instruction >> 21) & 31; + ppc_state.ppc_msr = ppc_state.ppc_gpr[reg_s]; } void ppc_mfspr(){ @@ -1405,8 +1407,7 @@ void ppc_b(){ adr_li = (quick_test < 0x2000000)? quick_test: (0xFC000000UL + quick_test); ppc_next_instruction_address = (uint32_t)(ppc_state.ppc_pc + adr_li); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } void ppc_bl(){ @@ -1415,8 +1416,7 @@ void ppc_bl(){ ppc_next_instruction_address = (uint32_t)(ppc_state.ppc_pc + adr_li); ppc_state.ppc_spr[8] = (uint32_t)(ppc_state.ppc_pc + 4); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } void ppc_ba(){ @@ -1424,8 +1424,7 @@ void ppc_ba(){ adr_li = (quick_test < 0x2000000)? quick_test: (0xFC000000UL + quick_test); ppc_next_instruction_address = adr_li; grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } void ppc_bla(){ @@ -1434,8 +1433,7 @@ void ppc_bla(){ ppc_next_instruction_address = adr_li; ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4; grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } void ppc_bc() @@ -1455,8 +1453,7 @@ void ppc_bc() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_pc + br_bd); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } } @@ -1477,8 +1474,7 @@ void ppc_bca() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = br_bd; grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } } @@ -1499,8 +1495,7 @@ void ppc_bcl() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_pc + br_bd); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4; } @@ -1522,8 +1517,7 @@ void ppc_bcla() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = br_bd; grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4; } @@ -1538,8 +1532,7 @@ void ppc_bcctr() if (cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_spr[9] & 0xFFFFFFFCUL); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } } @@ -1553,8 +1546,7 @@ void ppc_bcctrl() if (cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_spr[9] & 0xFFFFFFFCUL); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4; } @@ -1575,8 +1567,7 @@ void ppc_bclr() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_spr[8] & 0xFFFFFFFCUL); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } } @@ -1596,8 +1587,7 @@ void ppc_bclrl() if (ctr_ok && cnd_ok){ ppc_next_instruction_address = (ppc_state.ppc_spr[8] & 0xFFFFFFFCUL); grab_branch = 1; - bb_end = true; - bb_kind = BB_end_reason::BB_BRANCH; + bb_kind = BB_end_kind::BB_BRANCH; } ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4; } @@ -1750,12 +1740,11 @@ void ppc_rfi(){ ppc_next_instruction_address = ppc_state.ppc_spr[26] & 0xFFFFFFFCUL; grab_return = true; - bb_end = true; - bb_kind = BB_end_reason::BB_RFI; + bb_kind = BB_end_kind::BB_RFI; } void ppc_sc(){ - ppc_exception_handler(0x0C00, 0x20000); + ppc_exception_handler(Except_Type::EXC_SYSCALL, 0x20000); } void ppc_tw(){ @@ -1767,7 +1756,7 @@ void ppc_tw(){ (((int32_t)ppc_state.ppc_gpr[reg_a] == (int32_t)ppc_state.ppc_gpr[reg_b]) & (ppc_to & 0x04)) || \ ((ppc_state.ppc_gpr[reg_a] < ppc_state.ppc_gpr[reg_b]) & (ppc_to & 0x02)) || \ ((ppc_state.ppc_gpr[reg_a] > ppc_state.ppc_gpr[reg_b]) & (ppc_to & 0x01))){ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } } @@ -1780,7 +1769,7 @@ void ppc_twi(){ (((int32_t)ppc_state.ppc_gpr[reg_a] == simm) & (ppc_to & 0x04)) || \ ((ppc_state.ppc_gpr[reg_a] < (uint32_t)simm) & (ppc_to & 0x02)) || \ ((ppc_state.ppc_gpr[reg_a] > (uint32_t)simm) & (ppc_to & 0x01))){ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } } @@ -1838,7 +1827,7 @@ void ppc_dcbz(){ address_quickinsert_translate(0, (ppc_effective_address + 28), 4); } else{ - ppc_exception_handler(0x0600, 0x00000); + ppc_exception_handler(Except_Type::EXC_ALIGNMENT, 0x00000); } } @@ -1873,7 +1862,7 @@ void ppc_stbux(){ address_quickinsert_translate(ppc_result_d, ppc_effective_address, 1); } else{ - ppc_exception_handler(0x07000, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } ppc_result_a = ppc_effective_address; ppc_store_result_rega(); @@ -1996,7 +1985,7 @@ void ppc_lbzu(){ ppc_effective_address = ppc_result_a + grab_d; } else{ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } address_quickgrab_translate(ppc_effective_address, 1); ppc_result_d = return_value; @@ -2021,7 +2010,7 @@ void ppc_lbzux(){ ppc_effective_address = ppc_result_a + ppc_result_b; } else{ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } address_quickgrab_translate(ppc_effective_address, 1); ppc_result_d = return_value; @@ -2179,7 +2168,7 @@ void ppc_lwzu(){ ppc_effective_address = ppc_result_a + grab_d; } else{ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } address_quickgrab_translate(ppc_effective_address, 4); ppc_result_d = return_value; @@ -2204,7 +2193,7 @@ void ppc_lwzux(){ ppc_effective_address = ppc_result_a + ppc_result_b; } else{ - ppc_exception_handler(0x0700, 0x20000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x20000); } address_quickgrab_translate(ppc_effective_address, 4); ppc_result_d = return_value; @@ -2293,10 +2282,10 @@ void ppc_lswx(){ ppc_grab_regsdab(); //Invalid instruction forms if ((ppc_result_d == 0) && (ppc_result_a == 0)){ - ppc_exception_handler(0x0700, 0x100000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000); } if ((ppc_result_d == ppc_result_a) || (ppc_result_a == ppc_result_b)){ - ppc_exception_handler(0x0700, 0x100000); + ppc_exception_handler(Except_Type::EXC_PROGRAM, 0x100000); } ppc_effective_address = (reg_a == 0)?ppc_result_b:(ppc_result_a + ppc_result_b); grab_inb = ppc_state.ppc_spr[1] & 127; diff --git a/main.cpp b/main.cpp index 418e1c1..31902b5 100644 --- a/main.cpp +++ b/main.cpp @@ -126,75 +126,6 @@ uint64_t rev_endian64(uint64_t insert_int){ return ENDIAN_REVERSE64(insert_int); } -void ppc_exception_handler(uint32_t exception_type, uint32_t handle_args){ - ppc_next_instruction_address = 0x0; //used to construct a new address - grab_exception = true; - bb_end = 0; - bb_kind = BB_end_reason::BB_EXCEPTION; - - printf("MSR VALUE: %x \n Exception Type: %x", ppc_state.ppc_msr, exception_type); - - //Check ROM Exception Prefix - if (ppc_state.ppc_msr & 0x40){ - ppc_next_instruction_address |= 0xFFF00000; - } - else{ - ppc_next_instruction_address &= 0x0000FFFF; - } - - switch(exception_type){ - case 0x0100: //System Reset - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - ppc_state.ppc_spr[27] = ppc_state.ppc_msr; - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_next_instruction_address += 0x0100; - break; - /** - case 0x0200: //Machine Check - break; - case 0x0300: //DSI - break; - case 0x0400: //ISI - break; - **/ - case 0x0500: //External Interrupt - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - ppc_state.ppc_spr[27] = (ppc_state.ppc_msr & 0xFFFF); - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_next_instruction_address += 0x0500; - break; - case 0x0600: //Alignment Exception - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - ppc_state.ppc_spr[27] = (ppc_state.ppc_msr & 0xFFFF); - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_state.ppc_spr[19] = ppc_cur_instruction; - ppc_next_instruction_address += 0x0600; - case 0x0700: //Program; - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - handle_args += 0x10000; - ppc_state.ppc_spr[27] = handle_args + (ppc_state.ppc_msr & 0xFFFF); - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_next_instruction_address += 0x0700; - break; - case 0x0C00: //Sys Call - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - ppc_state.ppc_spr[27] = (ppc_state.ppc_msr & 0xFFFF); - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_next_instruction_address += 0x0C00; - break; - /** - case 0x0d: //Trace - break - **/ - default: - ppc_state.ppc_spr[26] = ((ppc_cur_instruction + 4) & 0xFFFFFFFC); - ppc_state.ppc_spr[27] = (ppc_state.ppc_msr & 0xFFFF); - ppc_state.ppc_msr = (ppc_state.ppc_msr & 0xFFFD0041); - ppc_next_instruction_address += exception_type; - - } -} - //Initialize the PPC's registers. void reg_init(){ for (uint32_t i = 0; i < 32; i++){