📄 armcopro.c
字号:
ARMul_State * state, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword value){ unsigned reg = BITS (16, 19); unsigned result; result = check_cp14_access (state, reg, BITS (0, 3), BITS (21, 23), BITS (5, 7)); if (result == ARMul_DONE) write_cp14_reg (reg, value); return result;}static unsignedXScale_cp14_read_reg( ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value){ * value = read_cp14_reg (reg); return TRUE;}static unsignedXScale_cp14_write_reg( ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword value){ write_cp14_reg (reg, value); return TRUE;}/* Here's ARMulator's MMU definition. A few things to note: 1) It has eight registers, but only two are defined. 2) You can only access its registers with MCR and MRC. 3) MMU Register 0 (ID) returns 0x41440110 4) Register 1 only has 4 bits defined. Bits 0 to 3 are unused, bit 4 controls 32/26 bit program space, bit 5 controls 32/26 bit data space, bit 6 controls late abort timimg and bit 7 controls big/little endian. */static ARMword MMUReg[8];static unsignedMMUInit (ARMul_State * state){ MMUReg[1] = state->prog32Sig << 4 | state->data32Sig << 5 | state->lateabtSig << 6 | state->bigendSig << 7; ARMul_ConsolePrint (state, ", MMU present"); return TRUE;}static unsignedMMUMRC (ARMul_State * state ATTRIBUTE_UNUSED, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword * value){ int reg = BITS (16, 19) & 7; if (reg == 0) *value = 0x41440110; else *value = MMUReg[reg]; return ARMul_DONE;}static unsignedMMUMCR (ARMul_State * state, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword value){ int reg = BITS (16, 19) & 7; MMUReg[reg] = value; if (reg == 1) { ARMword p,d,l,b; p = state->prog32Sig; d = state->data32Sig; l = state->lateabtSig; b = state->bigendSig; state->prog32Sig = value >> 4 & 1; state->data32Sig = value >> 5 & 1; state->lateabtSig = value >> 6 & 1; state->bigendSig = value >> 7 & 1; if ( p != state->prog32Sig || d != state->data32Sig || l != state->lateabtSig || b != state->bigendSig) /* Force ARMulator to notice these now. */ state->Emulate = CHANGEMODE; } return ARMul_DONE;}static unsignedMMURead (ARMul_State * state ATTRIBUTE_UNUSED, unsigned reg, ARMword * value){ if (reg == 0) *value = 0x41440110; else if (reg < 8) *value = MMUReg[reg]; return TRUE;}static unsignedMMUWrite (ARMul_State * state, unsigned reg, ARMword value){ if (reg < 8) MMUReg[reg] = value; if (reg == 1) { ARMword p,d,l,b; p = state->prog32Sig; d = state->data32Sig; l = state->lateabtSig; b = state->bigendSig; state->prog32Sig = value >> 4 & 1; state->data32Sig = value >> 5 & 1; state->lateabtSig = value >> 6 & 1; state->bigendSig = value >> 7 & 1; if ( p != state->prog32Sig || d != state->data32Sig || l != state->lateabtSig || b != state->bigendSig) /* Force ARMulator to notice these now. */ state->Emulate = CHANGEMODE; } return TRUE;}/* What follows is the Validation Suite Coprocessor. It uses two co-processor numbers (4 and 5) and has the follwing functionality. Sixteen registers. Both co-processor nuimbers can be used in an MCR and MRC to access these registers. CP 4 can LDC and STC to and from the registers. CP 4 and CP 5 CDP 0 will busy wait for the number of cycles specified by a CP register. CP 5 CDP 1 issues a FIQ after a number of cycles (specified in a CP register), CDP 2 issues an IRQW in the same way, CDP 3 and 4 turn of the FIQ and IRQ source, and CDP 5 stores a 32 bit time value in a CP register (actually it's the total number of N, S, I, C and F cyles). */static ARMword ValReg[16];static unsignedValLDC (ARMul_State * state ATTRIBUTE_UNUSED, unsigned type, ARMword instr, ARMword data){ static unsigned words; if (type != ARMul_DATA) words = 0; else { ValReg[BITS (12, 15)] = data; if (BIT (22)) /* It's a long access, get two words. */ if (words++ != 4) return ARMul_INC; } return ARMul_DONE;}static unsignedValSTC (ARMul_State * state ATTRIBUTE_UNUSED, unsigned type, ARMword instr, ARMword * data){ static unsigned words; if (type != ARMul_DATA) words = 0; else { * data = ValReg[BITS (12, 15)]; if (BIT (22)) /* It's a long access, get two words. */ if (words++ != 4) return ARMul_INC; } return ARMul_DONE;}static unsignedValMRC (ARMul_State * state ATTRIBUTE_UNUSED, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword * value){ *value = ValReg[BITS (16, 19)]; return ARMul_DONE;}static unsignedValMCR (ARMul_State * state ATTRIBUTE_UNUSED, unsigned type ATTRIBUTE_UNUSED, ARMword instr, ARMword value){ ValReg[BITS (16, 19)] = value; return ARMul_DONE;}static unsignedValCDP (ARMul_State * state, unsigned type, ARMword instr){ static unsigned long finish = 0; if (BITS (20, 23) != 0) return ARMul_CANT; if (type == ARMul_FIRST) { ARMword howlong; howlong = ValReg[BITS (0, 3)]; /* First cycle of a busy wait. */ finish = ARMul_Time (state) + howlong; return howlong == 0 ? ARMul_DONE : ARMul_BUSY; } else if (type == ARMul_BUSY) { if (ARMul_Time (state) >= finish) return ARMul_DONE; else return ARMul_BUSY; } return ARMul_CANT;}static unsignedDoAFIQ (ARMul_State * state){ state->NfiqSig = LOW; state->Exception++; return 0;}static unsignedDoAIRQ (ARMul_State * state){ state->NirqSig = LOW; state->Exception++; return 0;}static unsignedIntCDP (ARMul_State * state, unsigned type, ARMword instr){ static unsigned long finish; ARMword howlong; howlong = ValReg[BITS (0, 3)]; switch ((int) BITS (20, 23)) { case 0: if (type == ARMul_FIRST) { /* First cycle of a busy wait. */ finish = ARMul_Time (state) + howlong; return howlong == 0 ? ARMul_DONE : ARMul_BUSY; } else if (type == ARMul_BUSY) { if (ARMul_Time (state) >= finish) return ARMul_DONE; else return ARMul_BUSY; } return ARMul_DONE; case 1: if (howlong == 0) ARMul_Abort (state, ARMul_FIQV); else ARMul_ScheduleEvent (state, howlong, DoAFIQ); return ARMul_DONE; case 2: if (howlong == 0) ARMul_Abort (state, ARMul_IRQV); else ARMul_ScheduleEvent (state, howlong, DoAIRQ); return ARMul_DONE; case 3: state->NfiqSig = HIGH; state->Exception--; return ARMul_DONE; case 4: state->NirqSig = HIGH; state->Exception--; return ARMul_DONE; case 5: ValReg[BITS (0, 3)] = ARMul_Time (state); return ARMul_DONE; } return ARMul_CANT;}/* Install co-processor instruction handlers in this routine. */unsignedARMul_CoProInit (ARMul_State * state){ unsigned int i; /* Initialise tham all first. */ for (i = 0; i < 16; i++) ARMul_CoProDetach (state, i); /* Install CoPro Instruction handlers here. The format is: ARMul_CoProAttach (state, CP Number, Init routine, Exit routine LDC routine, STC routine, MRC routine, MCR routine, CDP routine, Read Reg routine, Write Reg routine). */ if (state->is_ep9312) { ARMul_CoProAttach (state, 4, NULL, NULL, DSPLDC4, DSPSTC4, DSPMRC4, DSPMCR4, DSPCDP4, NULL, NULL); ARMul_CoProAttach (state, 5, NULL, NULL, DSPLDC5, DSPSTC5, DSPMRC5, DSPMCR5, DSPCDP5, NULL, NULL); ARMul_CoProAttach (state, 6, NULL, NULL, NULL, NULL, DSPMRC6, DSPMCR6, DSPCDP6, NULL, NULL); } else { ARMul_CoProAttach (state, 4, NULL, NULL, ValLDC, ValSTC, ValMRC, ValMCR, ValCDP, NULL, NULL); ARMul_CoProAttach (state, 5, NULL, NULL, NULL, NULL, ValMRC, ValMCR, IntCDP, NULL, NULL); } if (state->is_XScale) { ARMul_CoProAttach (state, 13, XScale_cp13_init, NULL, XScale_cp13_LDC, XScale_cp13_STC, XScale_cp13_MRC, XScale_cp13_MCR, NULL, XScale_cp13_read_reg, XScale_cp13_write_reg); ARMul_CoProAttach (state, 14, XScale_cp14_init, NULL, XScale_cp14_LDC, XScale_cp14_STC, XScale_cp14_MRC, XScale_cp14_MCR, NULL, XScale_cp14_read_reg, XScale_cp14_write_reg); ARMul_CoProAttach (state, 15, XScale_cp15_init, NULL, NULL, NULL, XScale_cp15_MRC, XScale_cp15_MCR, NULL, XScale_cp15_read_reg, XScale_cp15_write_reg); } else { ARMul_CoProAttach (state, 15, MMUInit, NULL, NULL, NULL, MMUMRC, MMUMCR, NULL, MMURead, MMUWrite); } if (state->is_iWMMXt) { ARMul_CoProAttach (state, 0, NULL, NULL, IwmmxtLDC, IwmmxtSTC, NULL, NULL, IwmmxtCDP, NULL, NULL); ARMul_CoProAttach (state, 1, NULL, NULL, NULL, NULL, IwmmxtMRC, IwmmxtMCR, IwmmxtCDP, NULL, NULL); } /* No handlers below here. */ /* Call all the initialisation routines. */ for (i = 0; i < 16; i++) if (state->CPInit[i]) (state->CPInit[i]) (state); return TRUE;}/* Install co-processor finalisation routines in this routine. */voidARMul_CoProExit (ARMul_State * state){ register unsigned i; for (i = 0; i < 16; i++) if (state->CPExit[i]) (state->CPExit[i]) (state); for (i = 0; i < 16; i++) /* Detach all handlers. */ ARMul_CoProDetach (state, i);}/* Routines to hook Co-processors into ARMulator. */voidARMul_CoProAttach (ARMul_State * state, unsigned number, ARMul_CPInits * init, ARMul_CPExits * exit, ARMul_LDCs * ldc, ARMul_STCs * stc, ARMul_MRCs * mrc, ARMul_MCRs * mcr, ARMul_CDPs * cdp, ARMul_CPReads * read, ARMul_CPWrites * write){ if (init != NULL) state->CPInit[number] = init; if (exit != NULL) state->CPExit[number] = exit; if (ldc != NULL) state->LDC[number] = ldc; if (stc != NULL) state->STC[number] = stc; if (mrc != NULL) state->MRC[number] = mrc; if (mcr != NULL) state->MCR[number] = mcr; if (cdp != NULL) state->CDP[number] = cdp; if (read != NULL) state->CPRead[number] = read; if (write != NULL) state->CPWrite[number] = write;}voidARMul_CoProDetach (ARMul_State * state, unsigned number){ ARMul_CoProAttach (state, number, NULL, NULL, NoCoPro4R, NoCoPro4W, NoCoPro4W, NoCoPro4R, NoCoPro3R, NULL, NULL); state->CPInit[number] = NULL; state->CPExit[number] = NULL; state->CPRead[number] = NULL; state->CPWrite[number] = NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -