void MakeExecutable(int dummy, uint32 start, uint32 length) { if ((start >= ROMBase) && (start < (ROMBase + ROM_SIZE))) return; FlushCodeCache(start, start + length); }
extern pascal OSStatus MakeData68KExecutable(void *address, ByteCount count) // See comment in interface part. { OSErr err; #if TARGET_CPU_PPC assert(GetOSTrapAddress(_HWPriv) != GetToolTrapAddress(_Unimplemented)); #endif // Step 1. If we have _HWPriv, try calling FlushCodeCacheRange. If that // returns an error, call FlushCodeCache. Two important assumptions: // // a) any machine that has FlushCodeCacheRange implemented will necessarily // implement FlushCodeCache. // b) PowerPC computers always have FlushCodeCacheRange implemented, so // we don't need Mixed Mode glue for FlushCodeCache because we'll never // need it on a PowerPC. if ( GetOSTrapAddress(_HWPriv) != GetToolTrapAddress(_Unimplemented) ) { err = MoreFlushCodeCacheRange(address, count); #if TARGET_CPU_68K if (err != noErr) { assert(GetOSTrapAddress(_vCacheFlush) != GetToolTrapAddress(_Unimplemented)); FlushCodeCache(); } #else assert(err == noErr); #endif // Step 2. If we don't have _HWPriv, look to see whether _vCacheFlush // (ie FlushCodeCache) is implemented. If it is, we'll just call it. } else if ( GetOSTrapAddress(_vCacheFlush) != GetToolTrapAddress(_Unimplemented) ) { // The call to FlushCodeCache is conditionalised because // Universal Interfaces does not export the call unless // you're generating 68K code. *sigh* But that's OK because // all PowerPC machines have _HWPriv implemented, so this // code won't run. #if TARGET_CPU_68K FlushCodeCache(); #else assert(false); #endif // Step 3. Finally, if neither of these traps is implemented, we're just // going to execute 680x0 instructions directly. Note that we have to // execute different instructions based on the 680x0 variant. } else { // Obviously, this is only going to work (or indeed compile) if we're // generating 68K code. That's cool, because if we're generating PowerPC // code, we must end up running on a PowerPC, and that always has // FlushCodeCacheRange so we never get here. #if TARGET_CPU_68K { UInt32 gestaltResponse; if (Gestalt(gestaltProcessorType, (SInt32 *) &gestaltResponse) == noErr) { if (gestaltResponse >= gestalt68020) { if (gestaltResponse <= gestalt68030) { FlushCacheViaCACR(); } else { FlushCacheWithCPushA(); } } } } #else assert(false); #endif } // Basically this routine can't fail or, more accurately, // there are no expected failure cases. So we always return // noErr. In fact, the only reason this routine is defined to // return an error code is for symmetry with MakeDataPowerPCExecutable, // which has to return an error code in the classic 68K case. return noErr; }