static void std8250_io_do_cycle (void * state) { const int core_id = 0; /* currently, we only send uart interrupt to cpu0 */ e500_core_t * core = get_boot_core(); mpc8641d_io_t *io = &mpc8641d_io; std_16550_uart_t *uart = &io->uart[0]; /* if(!(core->msr & 0x8000)) return; */ if (uart->iir & 0x1) { if (uart->ier & 0x2) { /* THREI enabled */ //printf("In %s, THR interrupt\n", __FUNCTION__); uart->iir = (uart->iir & 0xf0) | 0x2; uart->lsr |= 0x60; } if (uart->ier & 0x1) { /* RDAI enabled */ struct timeval tv; unsigned char c; tv.tv_sec = 0; tv.tv_usec = 0; if (skyeye_uart_read (-1, &c, 1, &tv, NULL) > 0) { uart->rbr = (int) c; //printf("SKYEYE: io_do_cycle set ffiir or 04, now %x\n",pxa250_io.ffiir); uart->lsr |= 0x01; //Data ready uart->iir = (uart->iir & 0xf0) | 0x4; } } } if ((!(io->mpic.iivpr[UART_IRQ] & 0x80000000) && (core->msr & 0x8000) && !(core->ipr & 1 << UART_IRQ))) { //if(!(io->mpic.iivpr[UART_IRQ] & 0x80000000)){ if ((!(uart->iir & 0x1)) && (uart->ier & 0x3) ) { //printf ("In %s,uart int triggered. ier=0x%x\n", __FUNCTION__, uart->ier); core->ipr |= (1 << UART_IRQ); io->mpic.iivpr[UART_IRQ] |= 0x40000000; /* set activity bit in vpr */ io->pic_percpu.iack[core_id] = (io->pic_percpu. iack[core_id] & 0xFFFF0000) | (io->mpic. ipivpr [UART_IRQ] & 0xFFFF); skyeye_config_t *config = get_current_config(); if (!strcmp(config->os->os_name, "linux")) { io->pic_percpu.iack[core_id] = 0x2a; }else if (!strcmp(config->os->os_name, "vxworks")) { io->pic_percpu.iack[core_id] = 0x26; } //printf("In %s, ack=0x%x\n", __FUNCTION__, io->pic_percpu.iack[core_id]); core->ipi_flag = 1; /* we need to inform the core that npc is changed to exception vector */ ppc_exception (core, PPC_EXC_EXT_INT, 0, 0); } } }
// main opcode 63 static void ppc_opc_group_f2() { if ((gCPU.msr & MSR_FP) == 0) { ppc_exception(PPC_EXC_NO_FPU); return; } uint32 ext = PPC_OPC_EXT(gCPU.current_opc); if (ext & 16) { switch (ext & 0x1f) { case 18: ppc_opc_fdivx(); return; case 20: ppc_opc_fsubx(); return; case 21: ppc_opc_faddx(); return; case 22: ppc_opc_fsqrtx(); return; case 23: ppc_opc_fselx(); return; case 25: ppc_opc_fmulx(); return; case 26: ppc_opc_frsqrtex(); return; case 28: ppc_opc_fmsubx(); return; case 29: ppc_opc_fmaddx(); return; case 30: ppc_opc_fnmsubx(); return; case 31: ppc_opc_fnmaddx(); return; } } else { switch (ext) { case 0: ppc_opc_fcmpu(); return; case 12: ppc_opc_frspx(); return; case 14: ppc_opc_fctiwx(); return; case 15: ppc_opc_fctiwzx(); return; //-- case 32: ppc_opc_fcmpo(); return; case 38: ppc_opc_mtfsb1x(); return; case 40: ppc_opc_fnegx(); return; case 64: ppc_opc_mcrfs(); return; case 70: ppc_opc_mtfsb0x(); return; case 72: ppc_opc_fmrx(); return; case 134: ppc_opc_mtfsfix(); return; case 136: ppc_opc_fnabsx(); return; case 264: ppc_opc_fabsx(); return; case 583: ppc_opc_mffsx(); return; case 711: ppc_opc_mtfsfx(); return; } } ppc_opc_invalid(); }
// main opcode 59 static void ppc_opc_group_f1() { if ((gCPU.msr & MSR_FP) == 0) { ppc_exception(PPC_EXC_NO_FPU); return; } uint32 ext = PPC_OPC_EXT(gCPU.current_opc); switch (ext & 0x1f) { case 18: ppc_opc_fdivsx(); return; case 20: ppc_opc_fsubsx(); return; case 21: ppc_opc_faddsx(); return; case 22: ppc_opc_fsqrtsx(); return; case 24: ppc_opc_fresx(); return; case 25: ppc_opc_fmulsx(); return; case 28: ppc_opc_fmsubsx(); return; case 29: ppc_opc_fmaddsx(); return; case 30: ppc_opc_fnmsubsx(); return; case 31: ppc_opc_fnmaddsx(); return; } ppc_opc_invalid(); }
// main opcode 04 static void ppc_opc_group_v() { uint32 ext = PPC_OPC_EXT(gCPU.current_opc); #ifndef __VEC_EXC_OFF__ if ((gCPU.msr & MSR_VEC) == 0) { ppc_exception(PPC_EXC_NO_VEC); return; } #endif switch(ext & 0x1f) { case 16: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vmhraddshs(); else return ppc_opc_vmhaddshs(); case 17: return ppc_opc_vmladduhm(); case 18: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vmsummbm(); else return ppc_opc_vmsumubm(); case 19: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vmsumuhs(); else return ppc_opc_vmsumuhm(); case 20: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vmsumshs(); else return ppc_opc_vmsumshm(); case 21: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vperm(); else return ppc_opc_vsel(); case 22: return ppc_opc_vsldoi(); case 23: if (gCPU.current_opc & PPC_OPC_Rc) return ppc_opc_vnmsubfp(); else return ppc_opc_vmaddfp(); } switch(ext & 0x1ff) { case 3: return ppc_opc_vcmpequbx(); case 35: return ppc_opc_vcmpequhx(); case 67: return ppc_opc_vcmpequwx(); case 99: return ppc_opc_vcmpeqfpx(); case 227: return ppc_opc_vcmpgefpx(); case 259: return ppc_opc_vcmpgtubx(); case 291: return ppc_opc_vcmpgtuhx(); case 323: return ppc_opc_vcmpgtuwx(); case 355: return ppc_opc_vcmpgtfpx(); case 387: return ppc_opc_vcmpgtsbx(); case 419: return ppc_opc_vcmpgtshx(); case 451: return ppc_opc_vcmpgtswx(); case 483: return ppc_opc_vcmpbfpx(); } if (ext >= (sizeof ppc_opc_table_groupv / sizeof ppc_opc_table_groupv[0])) { return ppc_opc_invalid(); } return ppc_opc_table_groupv[ext](); }
void ppc_cpu_run() { /*gDebugger = new Debugger(); gDebugger->mAlwaysShowRegs = true;*/ PPC_CPU_TRACE("execution started at %08x\n", current_core->pc); uint ops=0; current_core->effective_code_page = 0xffffffff; // ppc_fpu_test(); // return; while (true) { current_core->npc = current_core->pc+4; if ((current_core->pc & ~0xfff) == current_core->effective_code_page) { current_core->current_opc = ppc_word_from_BE(*((uint32*)(¤t_core->physical_code_page[current_core->pc & 0xfff]))); ppc_debug_hook(); } else { int ret; if ((ret = ppc_direct_effective_memory_handle_code(current_core->pc & ~0xfff, current_core->physical_code_page))) { if (ret == PPC_MMU_EXC) { current_core->pc = current_core->npc; continue; } else { PPC_CPU_ERR("?\n"); } } current_core->effective_code_page = current_core->pc & ~0xfff; continue; } ppc_exec_opc(); ops++; current_core->ptb++; if (current_core->pdec == 0) { current_core->exception_pending = true; current_core->dec_exception = true; current_core->pdec=0xffffffff*TB_TO_PTB_FACTOR; } else { current_core->pdec--; } if ((ops & 0x3ffff)==0) { /* if (pic_check_interrupt()) { current_core->exception_pending = true; current_core->ext_exception = true; }*/ if ((ops & 0x0fffff)==0) { // uint32 j=0; // ppc_read_effective_word(0xc046b2f8, j); ht_printf("@%08x (%u ops) pdec: %08x lr: %08x\r", current_core->pc, ops, current_core->pdec, current_core->lr); #if 0 extern uint32 PIC_enable_low; extern uint32 PIC_enable_high; ht_printf("enable "); int x = 1; for (int i=0; i<31; i++) { if (PIC_enable_low & x) { ht_printf("%d ", i); } x<<=1; } x=1; for (int i=0; i<31; i++) { if (PIC_enable_high & x) { ht_printf("%d ", 32+i); } x<<=1; } ht_printf("\n"); #endif } } current_core->pc = current_core->npc; if (current_core->exception_pending) { if (current_core->stop_exception) { current_core->stop_exception = false; if (!current_core->dec_exception && !current_core->ext_exception) current_core->exception_pending = false; break; } if (current_core->msr & MSR_EE) { /*sys_lock_mutex(exception_mutex);*/ if (current_core->ext_exception) { ppc_exception(current_core, PPC_EXC_EXT_INT,0,0); current_core->ext_exception = false; current_core->pc = current_core->npc; if (!current_core->dec_exception) current_core->exception_pending = false; /*sys_unlock_mutex(exception_mutex);*/ continue; } if (current_core->dec_exception) { ppc_exception(current_core, PPC_EXC_DEC,0,0); current_core->dec_exception = false; current_core->pc = current_core->npc; current_core->exception_pending = false; /*sys_unlock_mutex(exception_mutex);*/ continue; } /*sys_unlock_mutex(exception_mutex);*/ PPC_CPU_ERR("no interrupt, but signaled?!\n"); } } #ifdef PPC_CPU_ENABLE_SINGLESTEP if (current_core->msr & MSR_SE) { if (current_core->singlestep_ignore) { current_core->singlestep_ignore = false; } else { ppc_exception(current_core, PPC_EXC_TRACE2); current_core->pc = current_core->npc; continue; } } #endif } }