mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-12-23 06:29:38 +00:00
ppcexec: pagewise MMU translation for code.
This commit is contained in:
parent
99288e44d1
commit
e76ef61f53
@ -160,6 +160,16 @@ 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 BB_end_reason {
|
||||
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;
|
||||
|
||||
extern bool grab_branch;
|
||||
extern bool grab_exception;
|
||||
extern bool grab_return;
|
||||
|
@ -6,6 +6,11 @@
|
||||
|
||||
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 */
|
||||
|
||||
uint64_t timebase_counter; /* internal timebase counter */
|
||||
|
||||
clock_t clock_test_begin; //Used to make sure the TBR does not increment so quickly.
|
||||
|
||||
/** Opcode lookup tables. */
|
||||
@ -508,6 +513,7 @@ void ppc_tbr_update()
|
||||
}
|
||||
|
||||
/** Execute PPC code as long as power is on. */
|
||||
#if 0
|
||||
void ppc_exec()
|
||||
{
|
||||
while (power_on){
|
||||
@ -531,8 +537,47 @@ void ppc_exec()
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ppc_exec()
|
||||
{
|
||||
uint32_t bb_start_la, page_start;
|
||||
uint8_t *pc_real;
|
||||
|
||||
/* start new basic block */
|
||||
bb_start_la = ppc_state.ppc_pc;
|
||||
bb_end = false;
|
||||
|
||||
/* initial MMU translation for the current code page. */
|
||||
pc_real = quickinstruction_translate(bb_start_la);
|
||||
|
||||
/* set current code page limits */
|
||||
page_start = bb_start_la & 0xFFFFF000;
|
||||
|
||||
while (power_on) {
|
||||
ppc_main_opcode();
|
||||
if (bb_end) {
|
||||
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) {
|
||||
page_start = bb_start_la & 0xFFFFF000;
|
||||
pc_real = quickinstruction_translate(bb_start_la);
|
||||
} else {
|
||||
pc_real += (int)bb_start_la - (int)ppc_state.ppc_pc;
|
||||
ppc_set_cur_instruction(pc_real);
|
||||
}
|
||||
ppc_state.ppc_pc = bb_start_la;
|
||||
bb_end = false;
|
||||
} else {
|
||||
ppc_state.ppc_pc += 4;
|
||||
pc_real += 4;
|
||||
ppc_set_cur_instruction(pc_real);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Execute one PPC instruction. */
|
||||
#if 0
|
||||
void ppc_exec_single()
|
||||
{
|
||||
quickinstruction_translate(ppc_state.ppc_pc);
|
||||
@ -553,8 +598,23 @@ void ppc_exec_single()
|
||||
ppc_tbr_update();
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ppc_exec_single()
|
||||
{
|
||||
quickinstruction_translate(ppc_state.ppc_pc);
|
||||
ppc_main_opcode();
|
||||
if (bb_end) {
|
||||
ppc_state.ppc_pc = ppc_next_instruction_address;
|
||||
bb_end = false;
|
||||
} else {
|
||||
ppc_state.ppc_pc += 4;
|
||||
}
|
||||
timebase_counter += 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Execute PPC code until goal_addr is reached. */
|
||||
#if 0
|
||||
void ppc_exec_until(uint32_t goal_addr)
|
||||
{
|
||||
while (ppc_state.ppc_pc != goal_addr) {
|
||||
@ -578,8 +638,47 @@ void ppc_exec_until(uint32_t goal_addr)
|
||||
ppc_cur_instruction = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
void ppc_exec_until(uint32_t goal_addr)
|
||||
{
|
||||
uint32_t bb_start_la, page_start;
|
||||
uint8_t *pc_real;
|
||||
|
||||
/* start new basic block */
|
||||
bb_start_la = ppc_state.ppc_pc;
|
||||
bb_end = false;
|
||||
|
||||
/* initial MMU translation for the current code page. */
|
||||
pc_real = quickinstruction_translate(bb_start_la);
|
||||
|
||||
/* set current code page limits */
|
||||
page_start = bb_start_la & 0xFFFFF000;
|
||||
|
||||
while (ppc_state.ppc_pc != goal_addr) {
|
||||
ppc_main_opcode();
|
||||
if (bb_end) {
|
||||
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) {
|
||||
page_start = bb_start_la & 0xFFFFF000;
|
||||
pc_real = quickinstruction_translate(bb_start_la);
|
||||
} else {
|
||||
pc_real += (int)bb_start_la - (int)ppc_state.ppc_pc;
|
||||
ppc_set_cur_instruction(pc_real);
|
||||
}
|
||||
ppc_state.ppc_pc = bb_start_la;
|
||||
bb_end = false;
|
||||
} else {
|
||||
ppc_state.ppc_pc += 4;
|
||||
pc_real += 4;
|
||||
ppc_set_cur_instruction(pc_real);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void ppc_init()
|
||||
{
|
||||
clock_test_begin = clock();
|
||||
timebase_counter = 0;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
PPC_BAT_entry ibat_array[4] = {{0}};
|
||||
PPC_BAT_entry dbat_array[4] = {{0}};
|
||||
|
||||
static inline void ppc_set_cur_instruction(const uint8_t *ptr)
|
||||
void ppc_set_cur_instruction(const uint8_t *ptr)
|
||||
{
|
||||
ppc_cur_instruction = READ_DWORD_BE(ptr);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ typedef struct PPC_BAT_entry {
|
||||
extern void ibat_update(uint32_t bat_reg);
|
||||
extern void dbat_update(uint32_t bat_reg);
|
||||
|
||||
extern void ppc_set_cur_instruction(const uint8_t *ptr);
|
||||
extern void address_quickinsert_translate(uint32_t value_insert, uint32_t address_grab, uint8_t num_bytes);
|
||||
extern void address_quickgrab_translate(uint32_t address_grab, uint8_t num_bytes);
|
||||
extern uint8_t *quickinstruction_translate(uint32_t address_grab);
|
||||
|
@ -1405,6 +1405,8 @@ 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_BRANCH;
|
||||
}
|
||||
|
||||
void ppc_bl(){
|
||||
@ -1413,6 +1415,8 @@ 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_BRANCH;
|
||||
}
|
||||
|
||||
void ppc_ba(){
|
||||
@ -1420,6 +1424,8 @@ 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_BRANCH;
|
||||
}
|
||||
|
||||
void ppc_bla(){
|
||||
@ -1428,6 +1434,8 @@ 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_BRANCH;
|
||||
}
|
||||
|
||||
void ppc_bc()
|
||||
@ -1447,6 +1455,8 @@ 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_BRANCH;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1467,6 +1477,8 @@ void ppc_bca()
|
||||
if (ctr_ok && cnd_ok){
|
||||
ppc_next_instruction_address = br_bd;
|
||||
grab_branch = 1;
|
||||
bb_end = true;
|
||||
bb_kind = BB_BRANCH;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1487,6 +1499,8 @@ 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_BRANCH;
|
||||
}
|
||||
ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4;
|
||||
}
|
||||
@ -1508,6 +1522,8 @@ void ppc_bcla()
|
||||
if (ctr_ok && cnd_ok){
|
||||
ppc_next_instruction_address = br_bd;
|
||||
grab_branch = 1;
|
||||
bb_end = true;
|
||||
bb_kind = BB_BRANCH;
|
||||
}
|
||||
ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4;
|
||||
}
|
||||
@ -1522,6 +1538,8 @@ 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_BRANCH;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1535,6 +1553,8 @@ 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_BRANCH;
|
||||
}
|
||||
ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4;
|
||||
}
|
||||
@ -1555,6 +1575,8 @@ 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_BRANCH;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1574,6 +1596,8 @@ 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_BRANCH;
|
||||
}
|
||||
ppc_state.ppc_spr[8] = ppc_state.ppc_pc + 4;
|
||||
}
|
||||
@ -1726,6 +1750,8 @@ void ppc_rfi(){
|
||||
ppc_next_instruction_address = ppc_state.ppc_spr[26] & 0xFFFFFFFCUL;
|
||||
|
||||
grab_return = true;
|
||||
bb_end = true;
|
||||
bb_kind = BB_RFI;
|
||||
}
|
||||
|
||||
void ppc_sc(){
|
||||
|
2
main.cpp
2
main.cpp
@ -129,6 +129,8 @@ uint64_t rev_endian64(uint64_t 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_EXCEPTION;
|
||||
|
||||
printf("MSR VALUE: %x \n Exception Type: %x", ppc_state.ppc_msr, exception_type);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user