ppcexec: pagewise MMU translation for code.

This commit is contained in:
Maxim Poliakovski 2020-01-03 21:01:02 +01:00
parent 99288e44d1
commit e76ef61f53
6 changed files with 139 additions and 1 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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);

View File

@ -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(){

View File

@ -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);