int AddDrv(iop_device_t *device) { int i, res = -1; int oldIntr; CpuSuspendIntr(&oldIntr); for (i = 0; i < MAX_DEVICES; i++) { if (dev_list[i] == NULL) break; } if (i >= MAX_DEVICES) { CpuResumeIntr(oldIntr); return res; } dev_list[i] = device; CpuResumeIntr(oldIntr); FlushIcache(); if ((res = device->ops->init(device)) < 0) { dev_list[i] = NULL; return(-1); } return(0); }
int _start(int argc, char *argv[]) { // install IOP debug system. if(iop_dbg_install() != 0) { //printf("Failed installing IOP debug system!\n"); return(1); // return "non-resident" } // register our IRX exports. if(RegisterLibraryEntries(&_exp_iopdebug) != 0) { iop_dbg_remove(); //printf("Error registering library!\n"); return(1); } FlushIcache(); FlushDcache(); //printf("IOPDEBUG installed!\n"); return(0); // return "resident" }
//-------------------------------------------------------------- void hookMODLOAD(void) { // get modload export table modinfo_t info; getModInfo("modload\0", &info); // hook modload's LoadStartModule function LoadStartModule = (void *)info.exports[7]; info.exports[7] = (void *)Hook_LoadStartModule; // hook modload's StartModule function StartModule = (void *)info.exports[8]; info.exports[8] = (void *)Hook_StartModule; // hook modload's LoadModuleBuffer LoadModuleBuffer = (void *)info.exports[10]; info.exports[10] = (void *)Hook_LoadModuleBuffer; // check modload version if (info.version > 0x102) { // hook modload's StopModule StopModule = (void *)info.exports[20]; info.exports[20] = (void *)Hook_StopModule; // hook modload's UnloadModule UnloadModule = (void *)info.exports[21]; info.exports[21] = (void *)Hook_UnloadModule; // hook modload's SearchModuleByName SearchModuleByName = (void *)info.exports[22]; info.exports[22] = (void *)Hook_SearchModuleByName; } // fix imports iop_library_t *lib = (iop_library_t *)((u32)info.exports - 0x14); struct irx_import_table *table; struct irx_import_stub *stub; FlushDcache(); // go through each table that imports the library for(table = lib->caller; table != NULL; table = table->next) { // go through each import in the table for(stub = (struct irx_import_stub *) table->stubs; stub->jump != 0; stub++) { // patch the stub to jump to the address specified in the library export table for "fno" stub->jump = 0x08000000 | (((u32) lib->exports[stub->fno] << 4) >> 6); } } FlushIcache(); }
const u8 *MipsJit::DoJit(u32 em_address, JitBlock *b) { js.cancel = false; js.blockStart = js.compilerPC = mips_->pc; js.lastContinuedPC = 0; js.initialBlockSize = 0; js.nextExit = 0; js.downcountAmount = 0; js.curBlock = b; js.compiling = true; js.inDelaySlot = false; js.PrefixStart(); b->normalEntry = GetCodePtr(); js.numInstructions = 0; while (js.compiling) { MIPSOpcode inst = Memory::Read_Opcode_JIT(js.compilerPC); js.downcountAmount += MIPSGetInstructionCycleEstimate(inst); MIPSCompileOp(inst); js.compilerPC += 4; js.numInstructions++; // Safety check, in case we get a bunch of really large jit ops without a lot of branching. if (GetSpaceLeft() < 0x800 || js.numInstructions >= JitBlockCache::MAX_BLOCK_INSTRUCTIONS) { FlushAll(); WriteExit(js.compilerPC, js.nextExit++); js.compiling = false; } } b->codeSize = GetCodePtr() - b->normalEntry; // Don't forget to zap the newly written instructions in the instruction cache! FlushIcache(); if (js.lastContinuedPC == 0) b->originalSize = js.numInstructions; else { // We continued at least once. Add the last proxy and set the originalSize correctly. blocks.ProxyBlock(js.blockStart, js.lastContinuedPC, (js.compilerPC - js.lastContinuedPC) / sizeof(u32), GetCodePtr()); b->originalSize = js.initialBlockSize; } return b->normalEntry; }
void JitArmILAsmRoutineManager::Generate() { enterCode = GetCodePtr(); PUSH(9, R4, R5, R6, R7, R8, R9, R10, R11, _LR); // Take care to 8-byte align stack for function calls. // We are misaligned here because of an odd number of args for PUSH. // It's not like x86 where you need to account for an extra 4 bytes // consumed by CALL. SUB(_SP, _SP, 4); MOVI2R(R0, (u32)&CoreTiming::downcount); MOVI2R(R9, (u32)&PowerPC::ppcState.spr[0]); FixupBranch skipToRealDispatcher = B(); dispatcher = GetCodePtr(); printf("ILDispatcher is %p\n", dispatcher); // Downcount Check // The result of slice decrementation should be in flags if somebody jumped here // IMPORTANT - We jump on negative, not carry!!! FixupBranch bail = B_CC(CC_MI); SetJumpTarget(skipToRealDispatcher); dispatcherNoCheck = GetCodePtr(); // This block of code gets the address of the compiled block of code // It runs though to the compiling portion if it isn't found LDR(R12, R9, PPCSTATE_OFF(pc));// Load the current PC into R12 Operand2 iCacheMask = Operand2(0xE, 2); // JIT_ICACHE_MASK BIC(R12, R12, iCacheMask); // R12 contains PC & JIT_ICACHE_MASK here. MOVI2R(R14, (u32)jit->GetBlockCache()->iCache); LDR(R12, R14, R12); // R12 contains iCache[PC & JIT_ICACHE_MASK] here // R12 Confirmed this is the correct iCache Location loaded. TST(R12, 0x80); // Test to see if it is a JIT block. SetCC(CC_EQ); // Success, it is our Jitblock. MOVI2R(R14, (u32)jit->GetBlockCache()->GetCodePointers()); // LDR R14 right here to get CodePointers()[0] pointer. LSL(R12, R12, 2); // Multiply by four because address locations are u32 in size LDR(R14, R14, R12); // Load the block address in to R14 B(R14); // No need to jump anywhere after here, the block will go back to dispatcher start SetCC(); // If we get to this point, that means that we don't have the block cached to execute // So call ArmJit to compile the block and then execute it. MOVI2R(R14, (u32)&Jit); BL(R14); B(dispatcherNoCheck); // fpException() // Floating Point Exception Check, Jumped to if false fpException = GetCodePtr(); LDR(R0, R9, PPCSTATE_OFF(Exceptions)); ORR(R0, R0, EXCEPTION_FPU_UNAVAILABLE); STR(R0, R9, PPCSTATE_OFF(Exceptions)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); LDR(R0, R9, PPCSTATE_OFF(npc)); STR(R0, R9, PPCSTATE_OFF(pc)); B(dispatcher); SetJumpTarget(bail); doTiming = GetCodePtr(); // XXX: In JIT64, Advance() gets called /after/ the exception checking // once it jumps back to the start of outerLoop QuickCallFunction(R14, (void*)&CoreTiming::Advance); // Does exception checking testExceptions = GetCodePtr(); LDR(R0, R9, PPCSTATE_OFF(pc)); STR(R0, R9, PPCSTATE_OFF(npc)); QuickCallFunction(R14, (void*)&PowerPC::CheckExceptions); LDR(R0, R9, PPCSTATE_OFF(npc)); STR(R0, R9, PPCSTATE_OFF(pc)); // Check the state pointer to see if we are exiting // Gets checked on every exception check MOVI2R(R0, (u32)PowerPC::GetStatePtr()); MVN(R1, 0); LDR(R0, R0); TST(R0, R1); FixupBranch Exit = B_CC(CC_NEQ); B(dispatcher); SetJumpTarget(Exit); ADD(_SP, _SP, 4); POP(9, R4, R5, R6, R7, R8, R9, R10, R11, _PC); // Returns GenerateCommon(); FlushIcache(); }