BOOL armcpu_irqException(armcpu_t *armcpu) { Status_Reg tmp; //TODO - remove GDB specific code //#ifdef GDB_STUB // armcpu->irq_flag = 0; //#endif tmp = armcpu->CPSR; armcpu_switchMode(armcpu, IRQ); //TODO - remove GDB specific code //#ifdef GDB_STUB // armcpu->R[14] = armcpu->next_instruction + 4; //#else armcpu->R[14] = armcpu->instruct_adr + 4; //#endif armcpu->SPSR = tmp; armcpu->CPSR.bits.T = 0; armcpu->CPSR.bits.I = 1; armcpu->next_instruction = armcpu->intVector + 0x18; armcpu->waitIRQ = 0; //must retain invariant of having next instruction to be executed prefetched //(yucky) armcpu_prefetch(armcpu); return TRUE; }
void armcpu_init(armcpu_t *armcpu, u32 adr) { armcpu->LDTBit = (armcpu->proc_ID==0); //arm9 is ARMv5 style. this should be renamed, or more likely, all references to this should poll a function to return an architecture level enum armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0); armcpu->waitIRQ = FALSE; armcpu->halt_IE_and_IF = FALSE; armcpu->intrWaitARM_state = 0; //#ifdef GDB_STUB // armcpu->irq_flag = 0; //#endif for(int i = 0; i < 16; ++i) { armcpu->R[i] = 0; if(armcpu->coproc[i]) free(armcpu->coproc[i]); armcpu->coproc[i] = NULL; } armcpu->CPSR.val = armcpu->SPSR.val = SYS; armcpu->R13_usr = armcpu->R14_usr = 0; armcpu->R13_svc = armcpu->R14_svc = 0; armcpu->R13_abt = armcpu->R14_abt = 0; armcpu->R13_und = armcpu->R14_und = 0; armcpu->R13_irq = armcpu->R14_irq = 0; armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0; armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0; //#ifdef GDB_STUB // armcpu->instruct_adr = adr; // armcpu->R[15] = adr + 8; //#else //armcpu->R[15] = adr; //#endif armcpu->next_instruction = adr; // only ARM9 have co-processor if (armcpu->proc_ID==0) armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu); //#ifndef GDB_STUB armcpu_prefetch(armcpu); //#endif }
void armcpu_init(armcpu_t *armcpu, u32 adr) { u32 i; armcpu->LDTBit = (armcpu->proc_ID==0); //Si ARM9 utiliser le syte v5 pour le load armcpu->intVector = 0xFFFF0000 * (armcpu->proc_ID==0); armcpu->waitIRQ = FALSE; armcpu->wirq = FALSE; #ifdef GDB_STUB armcpu->irq_flag = 0; #endif if(armcpu->coproc[15]) free(armcpu->coproc[15]); for(i = 0; i < 15; ++i) { armcpu->R[i] = 0; armcpu->coproc[i] = NULL; } armcpu->CPSR.val = armcpu->SPSR.val = SYS; armcpu->R13_usr = armcpu->R14_usr = 0; armcpu->R13_svc = armcpu->R14_svc = 0; armcpu->R13_abt = armcpu->R14_abt = 0; armcpu->R13_und = armcpu->R14_und = 0; armcpu->R13_irq = armcpu->R14_irq = 0; armcpu->R8_fiq = armcpu->R9_fiq = armcpu->R10_fiq = armcpu->R11_fiq = armcpu->R12_fiq = armcpu->R13_fiq = armcpu->R14_fiq = 0; armcpu->SPSR_svc.val = armcpu->SPSR_abt.val = armcpu->SPSR_und.val = armcpu->SPSR_irq.val = armcpu->SPSR_fiq.val = 0; #ifdef GDB_STUB armcpu->instruct_adr = adr; armcpu->R[15] = adr + 8; #else armcpu->R[15] = adr; #endif armcpu->next_instruction = adr; armcpu->coproc[15] = (armcp_t*)armcp15_new(armcpu); #ifndef GDB_STUB armcpu_prefetch(armcpu); #endif }
u32 armcpu_exec() { // Usually, fetching and executing are processed parallelly. // So this function stores the cycles of each process to // the variables below, and returns appropriate cycle count. u32 cFetch = 0; u32 cExecute = 0; //this assert is annoying. but sometimes it is handy. //assert(ARMPROC.instruct_adr!=0x00000000); //#ifdef DEVELOPER #if 0 if ((((ARMPROC.instruct_adr & 0x0F000000) == 0x0F000000) && (PROCNUM == 0)) || (((ARMPROC.instruct_adr & 0x0F000000) == 0x00000000) && (PROCNUM == 1))) { switch (ARMPROC.instruct_adr & 0xFFFF) { case 0x00000000: printf("BIOS%c: Reset!!!\n", PROCNUM?'7':'9'); emu_halt(); break; case 0x00000004: printf("BIOS%c: Undefined instruction\n", PROCNUM?'7':'9'); //emu_halt(); break; case 0x00000008: //printf("BIOS%c: SWI\n", PROCNUM?'7':'9'); break; case 0x0000000C: printf("BIOS%c: Prefetch Abort!!!\n", PROCNUM?'7':'9'); //emu_halt(); break; case 0x00000010: //printf("BIOS%c: Data Abort!!!\n", PROCNUM?'7':'9'); //emu_halt(); break; case 0x00000014: printf("BIOS%c: Reserved!!!\n", PROCNUM?'7':'9'); break; case 0x00000018: //printf("BIOS%c: IRQ\n", PROCNUM?'7':'9'); break; case 0x0000001C: printf("BIOS%c: Fast IRQ\n", PROCNUM?'7':'9'); break; } } #endif #if 0 //#ifdef GDB_STUB if (ARMPROC.stalled) { return STALLED_CYCLE_COUNT; } /* check for interrupts */ if (ARMPROC.irq_flag) { armcpu_irqException(&ARMPROC); } cFetch = armcpu_prefetch(&ARMPROC); if (ARMPROC.stalled) { return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch); } #endif //cFetch = armcpu_prefetch(&ARMPROC); //printf("%d: %08X\n",PROCNUM,ARMPROC.instruct_adr); if(ARMPROC.CPSR.bits.T == 0) { const u32 condition = CONDITION(ARMPROC.instruction); if( condition == 0x0E //fast path for unconditional instructions || (TEST_COND(condition, CODE(ARMPROC.instruction), ARMPROC.CPSR)) //handles any condition ) { #ifdef HAVE_LUA CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 4, ARMPROC.instruction, LUAMEMHOOK_EXEC); // should report even if condition=false? #endif if(PROCNUM==0) { #ifdef DEVELOPER DEBUG_statistics.instructionHits[0].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++; #endif cExecute = arm_instructions_set_0[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction); } else { #ifdef DEVELOPER DEBUG_statistics.instructionHits[1].arm[INSTRUCTION_INDEX(ARMPROC.instruction)]++; #endif cExecute = arm_instructions_set_1[INSTRUCTION_INDEX(ARMPROC.instruction)](ARMPROC.instruction); } } else cExecute = 1; // If condition=false: 1S cycle #ifdef GDB_STUB if ( ARMPROC.post_ex_fn != NULL) { /* call the external post execute function */ ARMPROC.post_ex_fn(ARMPROC.post_ex_fn_data, ARMPROC.instruct_adr, 0); } ARMPROC.mem_if->prefetch32( ARMPROC.mem_if->data, ARMPROC.next_instruction); #endif cFetch = armcpu_prefetch<PROCNUM>(); return MMU_fetchExecuteCycles<PROCNUM>(cExecute, cFetch); } #ifdef HAVE_LUA CallRegisteredLuaMemHook(ARMPROC.instruct_adr, 2, ARMPROC.instruction, LUAMEMHOOK_EXEC); #endif if(PROCNUM==0) { #ifdef DEVELOPER DEBUG_statistics.instructionHits[0].thumb[ARMPROC.instruction>>6]++; #endif cExecute = thumb_instructions_set_0[ARMPROC.instruction>>6](ARMPROC.instruction); }