int FASTCALL ppc_write_effective_byte(uint32 addr, uint8 data) { uint32 p; int r; e500_core_t* current_core = get_current_core(); PPC_CPU_State* cpu = get_current_cpu(); if (!((r=ppc_effective_to_physical(current_core, addr, PPC_MMU_WRITE, &p)))) { //ppc_io_write_byte (¤t_core-> p, data); //printf("DBG:in %s,addr=0x%x,p=0x%x, data=0x%x, pc=0x%x\n", __FUNCTION__, addr,p, data, current_core->pc); //printf("DBG:ccsr=0x%x,CCSR_BASE=0x%x",current_core->ccsr.ccsr,GET_CCSR_BASE(current_core->ccsr.ccsr)); if(in_ccsr_range(p)){ int offset = p - current_core->get_ccsr_base(cpu->ccsr); //skyeye_config.mach->mach_io_write_byte(&gCPU, offset, data); skyeye_config_t* config = get_current_config(); config->mach->mach_io_write_byte(cpu, offset, data); return r; //printf("DBG:write to CCSR,value=0x%x,offset=0x%x\n", data, offset); } else{ bus_write(8, p, data); //fprintf(stderr,"in %s, can not find address 0x%x,pc=0x%x,ccsr=0x%x\n", __FUNCTION__, p, current_core->pc, gCPU.ccsr); //skyeye_exit(-1); } } return r; }
/* * cmpi Compare Immediate * .443 */ void ppc_opc_cmpi() { uint32 cr; int rA; e500_core_t* current_core = get_current_core(); uint32 imm; PPC_OPC_TEMPL_D_SImm(current_core->current_opc, cr, rA, imm); cr >>= 2; sint32 a = current_core->gpr[rA]; sint32 b = imm; uint32 c; /* if (!VALGRIND_CHECK_READABLE(a, sizeof a)) { ht_printf("%08x <--i\n", current_core->pc); // SINGLESTEP(""); }*/ if (a < b) { c = 8; } else if (a > b) { c = 4; } else { c = 2; } if (current_core->xer & XER_SO) c |= 1; cr = 7-cr; current_core->cr &= ppc_cmp_and_mask[cr]; current_core->cr |= c<<(cr*4); //fprintf(stderr,"in %s,rA=%d,gpr[rA]=0x%d,im=%d,c=%d\n",__FUNCTION__,rA,current_core->gpr[rA],imm,c); }
int ppc_read_effective_byte(uint32 addr, uint8 *result) { e500_core_t * current_core = get_current_core(); PPC_CPU_State* cpu = get_current_cpu(); uint32 p; int r; if (!(r = ppc_effective_to_physical(current_core, addr, PPC_MMU_READ, &p))) { //ppc_io_read_byte (¤t_core-> p); //printf("\nDBG:in %s,addr=0x%x,p=0x%x\n", __FUNCTION__, addr,p); //printf("DBG:ccsr=0x%x,CCSR_BASE=0x%x\n",current_core->ccsr.ccsr,GET_CCSR_BASE(current_core->ccsr.ccsr)); if(in_ccsr_range(p)){ int offset = p - current_core->get_ccsr_base(cpu->ccsr); skyeye_config_t* config = get_current_config(); *result = config->mach->mach_io_read_byte(cpu, offset); //*result = skyeye_config.mach->mach_io_read_byte(&gCPU, offset); //printf("In %s, offset=0x%x, *result=0x%x\n", __FUNCTION__, offset, *result); return r; } else{ if(bus_read(8, p, result) != 0){ } //fprintf(stderr,"in %s, can not find address 0x%x,pc=0x%x\n", __FUNCTION__, p, current_core->pc); //skyeye_exit(-1); } } return r; }
int FASTCALL ppc_write_effective_word(uint32 addr, uint32 data) { PPC_CPU_State* cpu = get_current_cpu(); e500_core_t * current_core = get_current_core(); uint32 p; int r; if(addr & 0x3){ //ppc_exception for unalign } if (!((r=ppc_effective_to_physical(current_core, addr, PPC_MMU_WRITE, &p)))) { if(in_ccsr_range(p)){ int offset = p - current_core->get_ccsr_base(cpu->ccsr); //skyeye_config.mach->mach_io_write_word(&gCPU, offset, data); skyeye_config_t* config = get_current_config(); config->mach->mach_io_write_word(cpu, offset, data); //printf("DBG:write to CCSR,value=0x%x,offset=0x%x,pc=0x%x\n", data, offset,current_core->pc); } else{ bus_write(32, p, data); //fprintf(stderr,"in %s, can not find address 0x%x,pc=0x%x,ccsr_base=0x%x, ccsr=0x%x\n", __FUNCTION__, p, current_core->pc, GET_CCSR_BASE(gCPU.ccsr), gCPU.ccsr); //skyeye_exit(-1); } } return r; }
/* * oris OR Immediate Shifted * .606 */ void ppc_opc_oris() { int rS, rA; e500_core_t* current_core = get_current_core(); uint32 imm; PPC_OPC_TEMPL_D_Shift16(current_core->current_opc, rS, rA, imm); current_core->gpr[rA] = current_core->gpr[rS] | imm; }
static void update_int(){ MIPS_State* mstate = get_current_core(); if(io.int_ctrl[0].req0int & 0x1){ //printf("hardware int happened!\n"); mstate->cp0[Cause] |= 1 << Cause_IP2; process_exception(mstate, EXC_Int, common_vector); } }
/* * addis Add Immediate Shifted * .428 */ void ppc_opc_addis() { int rD, rA; uint32 imm; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_D_Shift16(current_core->current_opc, rD, rA, imm); current_core->gpr[rD] = (rA ? current_core->gpr[rA] : 0) + imm; }
/* * mulli Multiply Low Immediate * .598 */ void ppc_opc_mulli() { int rD, rA; e500_core_t* current_core = get_current_core(); uint32 imm; PPC_OPC_TEMPL_D_SImm(current_core->current_opc, rD, rA, imm); // FIXME: signed / unsigned correct? current_core->gpr[rD] = current_core->gpr[rA] * imm; }
/* * addi Add Immediate * .425 */ void ppc_opc_addi() { int rD, rA; uint32 imm; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_D_SImm(current_core->current_opc, rD, rA, imm); current_core->gpr[rD] = (rA ? current_core->gpr[rA] : 0) + imm; //fprintf(stderr, "in %s,rD=0x%x,rA=0x%x,imm=0x%x,current_core->gpr[rD]=0x%x\n",__FUNCTION__, rD,rA,imm,current_core->gpr[rD]); }
/* * andis. AND Immediate Shifted * .434 */ void ppc_opc_andis_() { int rS, rA; uint32 imm; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_D_Shift16(current_core->current_opc, rS, rA, imm); current_core->gpr[rA] = current_core->gpr[rS] & imm; // update cr0 flags ppc_update_cr0(current_core->gpr[rA]); }
/* * orcx OR with Complement * .604 */ void ppc_opc_orcx() { int rS, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, rS, rA, rB); current_core->gpr[rA] = current_core->gpr[rS] | ~current_core->gpr[rB]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rA]); } }
/* * crorc Condition Register OR with Complement * .454 */ void ppc_opc_crorc() { int crD, crA, crB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, crD, crA, crB); if ((current_core->cr & (1<<(31-crA))) || !(current_core->cr & (1<<(31-crB)))) { current_core->cr |= (1<<(31-crD)); } else { current_core->cr &= ~(1<<(31-crD)); } }
/* * addx Add * .422 */ void ppc_opc_addx() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); current_core->gpr[rD] = current_core->gpr[rA] + current_core->gpr[rB]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }
/* * negx Negate * .601 */ void ppc_opc_negx() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); PPC_OPC_ASSERT(rB == 0); current_core->gpr[rD] = -current_core->gpr[rA]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }
/* * crnor Condition Register NOR * .452 */ void ppc_opc_crnor() { int crD, crA, crB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, crD, crA, crB); uint32 t = (1<<(31-crA)) | (1<<(31-crB)); if (!(current_core->cr & t)) { current_core->cr |= (1<<(31-crD)); } else { current_core->cr &= ~(1<<(31-crD)); } }
static uint32_t mpc8572_io_read_halfword (void *state, uint32_t offset) { PPC_CPU_State* cpu = get_current_cpu(); e500_core_t *current_core = get_current_core(); mpc8572_io_t *io = &mpc8572_io; //int offset = p - GET_CCSR_BASE (io->ccsr.ccsr); //printf("DBG:read CCSR,offset=0x%x,pc=0x%x\n", offset, current_core->pc); if (offset >= 0x919C0 && offset <= 0x919E0) { switch (offset) { default: /* fprintf (stderr, "in %s, error when read CCSR.offset=0x%x,pc=0x%x\n", __FUNCTION__, offset, current_core->pc); */ skyeye_exit (-1); } } if (offset >= 0xE0000 && offset <= 0xE0020) { switch (offset) { case 0xE0000: return io->por_conf.porpllsr; default: /* fprintf (stderr, "in %s, error when read CCSR.offset=0x%x,pc=0x%x\n", __FUNCTION__, offset, current_core->pc); */ skyeye_exit (-1); } } switch (offset) { case 0x0: return cpu->ccsr; case 0x90C80: return io->sccr; case 0x8004: return io->pci_cfg.cfg_data; case 0x8006: return io->pci_cfg.cfg_data; default: fprintf (stderr, "in %s, error when read CCSR.offset=0x%x,pc=0x%x\n", __FUNCTION__, offset, current_core->pc); return 0; //skyeye_exit(-1); } }
/* * addox Add with Overflow * .422 */ void ppc_opc_addox() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); current_core->gpr[rD] = current_core->gpr[rA] + current_core->gpr[rB]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } // update XER flags PPC_ALU_ERR("addox unimplemented\n"); }
/* * rlwnmx Rotate Left Word then AND with Mask * .620 */ void ppc_opc_rlwnmx() { int rS, rA, rB, MB, ME; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_M(current_core->current_opc, rS, rA, rB, MB, ME); uint32 v = ppc_word_rotl(current_core->gpr[rS], current_core->gpr[rB]); uint32 mask = ppc_mask(MB, ME); current_core->gpr[rA] = v & mask; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rA]); } }
/* * divwux Divide Word Unsigned * .472 */ void ppc_opc_divwux() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); if (!current_core->gpr[rB]) { PPC_ALU_WARN("division by zero @%08x\n", current_core->pc); } current_core->gpr[rD] = current_core->gpr[rA] / current_core->gpr[rB]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }
/* * mulhwux Multiply High Word Unsigned * .596 */ void ppc_opc_mulhwux() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); uint64 a = current_core->gpr[rA]; uint64 b = current_core->gpr[rB]; uint64 c = a*b; current_core->gpr[rD] = c>>32; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }
/* * addic Add Immediate Carrying * .426 */ void ppc_opc_addic() { int rD, rA; uint32 imm; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_D_SImm(current_core->current_opc, rD, rA, imm); uint32 a = current_core->gpr[rA]; current_core->gpr[rD] = a + imm; // update XER if (current_core->gpr[rD] < a) { current_core->xer |= XER_CA; } else { current_core->xer &= ~XER_CA; } }
/* * mulhwx Multiply High Word * .595 */ void ppc_opc_mulhwx() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); sint64 a = (sint32)current_core->gpr[rA]; sint64 b = (sint32)current_core->gpr[rB]; sint64 c = a*b; current_core->gpr[rD] = ((uint64)c)>>32; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); // PPC_ALU_WARN("mulhw. correct?\n"); } }
/* * divwuox Divide Word Unsigned with Overflow * .472 */ void ppc_opc_divwuox() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); if (!current_core->gpr[rB]) { // PPC_ALU_ERR("division by zero\n"); } current_core->gpr[rD] = current_core->gpr[rA] / current_core->gpr[rB]; if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } // update XER flags PPC_ALU_ERR("divwuox unimplemented\n"); }
/* * slwx Shift Left Word * .625 */ void ppc_opc_slwx() { int rS, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, rS, rA, rB); uint32 s = current_core->gpr[rB] & 0x3f; if (s > 31) { current_core->gpr[rA] = 0; } else { current_core->gpr[rA] = current_core->gpr[rS] << s; } if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rA]); } }
/* * extshx Extend Sign Half Word * .482 */ void ppc_opc_extshx() { int rS, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, rS, rA, rB); PPC_OPC_ASSERT(rB==0); current_core->gpr[rA] = current_core->gpr[rS]; if (current_core->gpr[rA] & 0x8000) { current_core->gpr[rA] |= 0xffff0000; } else { current_core->gpr[rA] &= ~0xffff0000; } if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rA]); } }
static void gs32eb1_io_do_cycle (void * state) { MIPS_State* mstate = get_current_core(); #if 1 if(!(mstate->cp0[Cause] & (1 << Cause_IP4))){ /* UART receive interrupt enable */ int uart_int_enable = ((mstate->cp0[SR] & (1 << SR_IM4)) >> SR_IM4) & (mstate->cp0[SR] & (1 << SR_IEC)); // UART interrupt enable struct timeval tv; unsigned char c; tv.tv_sec = 0; tv.tv_usec = 0; if(skyeye_uart_read(-1, &c, 1, &tv, NULL) > 0) { io.uart[0].thr = (int) c; //printf("SKYEYE: io_do_cycle set intcause = %x\n",io.uart[0].intcause); io.uart[0].lsr |= 0x01; //Data ready //printf("In %s, uart receive int,uart_int_enable=0x%x, SR=0x%x\n", __FUNCTION__, uart_int_enable, mstate->cp0[SR]); io.uart[0].iir |= 0x4; //Rx idle } /* if(skyeye_uart_read(-1, &c, 1, &tv, NULL) > 0) */ // UART interrupt enable if(uart_int_enable){ if ((io.uart[0].ier & 0x1) && (io.uart[0].iir & 0x4)) { io.uart[0].iir &= ~0x1; /* Set uart interrupt bit in IP section of Cause register */ mstate->cp0[Cause] |= 1 << Cause_IP4; /* Set ExcCode to zero in Cause register */ process_exception(mstate, EXC_Int, common_vector); } #if 1 if (io.uart[0].ier & 0x2) { io.uart[0].iir |= 0x2; io.uart[0].iir &= ~0x1; io.uart[0].lsr |= 0x60; //printf("THR interrupt\n"); /* Set uart interrupt bit in IP section of Cause register */ mstate->cp0[Cause] |= 1 << Cause_IP4; /* Set ExcCode to zero in Cause register */ process_exception(mstate, EXC_Int, common_vector); } #endif } }
int FASTCALL ppc_read_effective_word(uint32 addr, uint32 *result) { e500_core_t* current_core = get_current_core(); PPC_CPU_State* cpu = get_current_cpu(); uint32 p; int r; if (!(r = ppc_effective_to_physical(current_core, addr, PPC_MMU_READ, &p))) { if(in_ccsr_range(p)){ skyeye_config_t *config = get_current_config(); *result = config->mach->mach_io_read_word(cpu, (p - current_core->get_ccsr_base(cpu->ccsr))); } else{ if(bus_read(32, p, result) != 0){ } } } return r; }
/* * srawx Shift Right Algebraic Word * .628 */ void ppc_opc_srawx() { int rS, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_X(current_core->current_opc, rS, rA, rB); uint32 SH = current_core->gpr[rB] & 0x3f; current_core->gpr[rA] = current_core->gpr[rS]; current_core->xer &= ~XER_CA; if (current_core->gpr[rA] & 0x80000000) { uint32 ca = 0; uint i; for (i=0; i < SH; i++) { if (current_core->gpr[rA] & 1) ca = 1; current_core->gpr[rA] >>= 1; current_core->gpr[rA] |= 0x80000000; } if (ca) current_core->xer |= XER_CA; } else {
/* * addcx Add Carrying * .423 */ void ppc_opc_addcx() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); uint32 a = current_core->gpr[rA]; current_core->gpr[rD] = a + current_core->gpr[rB]; // update xer if (current_core->gpr[rD] < a) { current_core->xer |= XER_CA; } else { current_core->xer &= ~XER_CA; } if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }
/* * addmex Add to Minus One Extended * .429 */ void ppc_opc_addmex() { int rD, rA, rB; e500_core_t* current_core = get_current_core(); PPC_OPC_TEMPL_XO(current_core->current_opc, rD, rA, rB); PPC_OPC_ASSERT(rB == 0); uint32 a = current_core->gpr[rA]; uint32 ca = ((current_core->xer&XER_CA)?1:0); current_core->gpr[rD] = a + ca + 0xffffffff; if (a || ca) { current_core->xer |= XER_CA; } else { current_core->xer &= ~XER_CA; } if (current_core->current_opc & PPC_OPC_Rc) { // update cr0 flags ppc_update_cr0(current_core->gpr[rD]); } }