/* * This function contains the main interpreter loop. Java * ByteCode instructions are executed one at a time. Before * calling this function the core register should contain * the correct value. */ execute() { // initialise register values printf("Interpreter started\n"); initCollector(); thread = getRef(core, CORE_RUNNING); loadRegisters(); // used to mimic a time slice int maxSize = 50; int count = 0; // execute the next instruction, indefinitely void (*implementation)(); int index; unsigned char bytecode; for (;;) { bytecode = code[pc]; dbgCodes[dbgIndex++] = bytecode; if (dbgIndex == 50) { dbgIndex = 0; } //printf("0x%X\n", bytecode); implementation = distributor[bytecode]; implementation(); count++; // check if another thread needs to be scheduled if (thread == NULL || count >= maxSize) { if (thread != NULL) { saveRegisters(); } scheduleNextThread(); //wakeSleepingThreads(); count = 0; } } }
void IOI2CLM6x::processPowerEvent ( UInt32 eventType ) { switch ( eventType ) { case kI2CPowerEvent_OFF: case kI2CPowerEvent_SLEEP: { require_success( saveRegisters(), IOI2CLM6x_processPowerEvent_saveRegistersErr ); fRegistersAreSaved = true; break; } case kI2CPowerEvent_ON: case kI2CPowerEvent_WAKE: { if ( fRegistersAreSaved ) { // Full Power State require_success( restoreRegisters(), IOI2CLM6x_processPowerEvent_restoreRegistersErr ); fRegistersAreSaved = false; } break; } case kI2CPowerEvent_STARTUP: { require_success( initHW(), IOI2CLM6x_processPowerEvent_initHWErr ); break; } } IOI2CLM6x_processPowerEvent_initHWErr: IOI2CLM6x_processPowerEvent_saveRegistersErr: return; IOI2CLM6x_processPowerEvent_restoreRegistersErr: fRegistersAreSaved = false; return; }
IOReturn AppleLM8x::setPowerState(unsigned long whatState, IOService *dontCare) { DLOG("AppleLM8x::setPowerState called with state:%lu\n", whatState); if ( (whatState == kLM8xOffState) ) { // No Power State systemIsRestarting = TRUE; // set flag to reflect shutting down state. if ( saveRegisters() != kIOReturnSuccess ) IOLog("AppleLM8x::powerStateWillChangeTo(0x%x) failed to save registers.\n", kLM8xAddr<<1); } if ( (whatState == kLM8xOnState) ) { // Full Power State if ( restoreRegisters() != kIOReturnSuccess ) IOLog("AppleLM8x::powerStateWillChangeTo(0x%x) failed to restore registers.\n", kLM8xAddr<<1); systemIsRestarting = FALSE; // set flag to reflect we are not shutting down. } return IOPMAckImplied; }
// Yield to another user thread. void yield(void) { labelhack(Resume); DEBUG_PRINT("Put self in readyQ and suspend\n"); Registers saveArea; void* localStubBase = stubBase; DEBUG_PRINT("stacklet %p cannot be freed\n", stubBase - STACKLET_SIZE); DEBUG_PRINT("Store stubBase in localStubBase %p\n", localStubBase); saveRegisters(); void* stackPointer; getStackPointer(stackPointer); enqReadyQ(&&Resume, stackPointer); suspendStub(); Resume: restoreRegisters(); stubBase = localStubBase; DEBUG_PRINT("stacklet %p can be freed\n", stubBase - STACKLET_SIZE); DEBUG_PRINT("Restore stubBase to be %p.\n", stubBase); DEBUG_PRINT("Resumed a ready thread.\n"); }
bool AppleLM8x::start(IOService *provider) { mach_timespec_t WaitTimeOut; OSData *t; int *reg; IOReturn status; // Proper etiquette if ( !(super::start(provider)) ) return false; // Set flag to reflect non-restart state systemIsRestarting = FALSE; // Try and get the reg property if ( !(t = OSDynamicCast(OSData, provider->getProperty("reg"))) ) { IOLog( "AppleLM8x::start couldn't find 'reg' property in registry.\n"); return false; } // We have the reg property, lets make local copy if ( !(reg = (int*)t->getBytesNoCopy()) ) { IOLog( "AppleLM8x::start 'reg' property is present but empty.\n"); return false; } kLM8xBus = (UInt8)(*reg >> 8); // Determine I2C bus kLM8xAddr = (UInt8)(*reg >> 1); // Determine true address of device // Use a 30 second timeout when calling waitForService() WaitTimeOut.tv_sec = 30; WaitTimeOut.tv_nsec = 0; // Create some symbols for later use sOpenI2Cbus = OSSymbol::withCStringNoCopy(kOpenI2Cbus); sCloseI2Cbus = OSSymbol::withCStringNoCopy(kCloseI2Cbus); sSetPollingMode = OSSymbol::withCStringNoCopy(kSetPollingMode); sSetStandardSubMode = OSSymbol::withCStringNoCopy(kSetStandardSubMode); sSetCombinedMode = OSSymbol::withCStringNoCopy(kSetCombinedMode); sWriteI2Cbus = OSSymbol::withCStringNoCopy(kWriteI2Cbus); sReadI2Cbus = OSSymbol::withCStringNoCopy(kReadI2Cbus); sGetSensorValueSym = OSSymbol::withCString("getSensorValue"); interface = OSDynamicCast(IOService, provider->getParentEntry(gIOServicePlane)); if(interface == NULL) { IOLog("AppleLM8x::start(0x%x) failed to get i2c interface\n", kLM8xAddr<<1); return(false); } DLOG("AppleLM8x::start(0x%x) got i2c interface %s\n", kLM8xAddr<<1, interface->getName()); // Configure the LM87 if( initHW(provider) != kIOReturnSuccess ) { IOLog("AppleLM8x::start(0x%x) failed to initialize sensor.\n", kLM8xAddr<<1); return false; } // Save registers for PM if ( saveRegisters() != kIOReturnSuccess ) IOLog("AppleLM8x::powerStateWillChangeTo(0x%x) failed to save registers.\n", kLM8xAddr<<1); // Initialize Power Management superclass variables from IOService.h PMinit(); // Register as controlling driver from IOService.h status = registerPowerDriver( this, (IOPMPowerState *) ourPowerStates, kLM8xNumStates ); if (status != kIOReturnSuccess) { IOLog("%s: Failed to registerPowerDriver.\n", getName()); } // Join the Power Management tree from IOService.h provider->joinPMtree( this); // Install power change handler (for restart notification) registerPrioritySleepWakeInterest(&sysPowerDownHandler, this, 0); // Register so others can find us with a waitForService() registerService(); // Parse sensor properties and create nubs publishChildren(provider); return true; }
CPURegisterEditor::CPURegisterEditor() { setTitle("CPU Register Editor"); layout.setMargin(5); regALabel.setText("A:"); regAValue.setFont(application->monospaceFont); regXLabel.setText("X:"); regXValue.setFont(application->monospaceFont); regYLabel.setText("Y:"); regYValue.setFont(application->monospaceFont); regSLabel.setText("S:"); regSValue.setFont(application->monospaceFont); regDLabel.setText("D:"); regDValue.setFont(application->monospaceFont); regDBLabel.setText("DB:"); regDBValue.setFont(application->monospaceFont); flagN.setText("N"); flagV.setText("V"); flagM.setText("M"); flagX.setText("X"); flagD.setText("D"); flagI.setText("I"); flagZ.setText("Z"); flagC.setText("C"); flagE.setText("E"); update.setText("Update"); loadRegisters(); layout.append(primaryLayout, {~0, 0}, 5); primaryLayout.append(regALabel, {0, 0}, 5); primaryLayout.append(regAValue, {0, 0}, 5); primaryLayout.append(regXLabel, {0, 0}, 5); primaryLayout.append(regXValue, {0, 0}, 5); primaryLayout.append(regYLabel, {0, 0}, 5); primaryLayout.append(regYValue, {0, 0}, 5); primaryLayout.append(regSLabel, {0, 0}, 5); primaryLayout.append(regSValue, {0, 0}, 5); primaryLayout.append(regDLabel, {0, 0}, 5); primaryLayout.append(regDValue, {0, 0}, 5); primaryLayout.append(regDBLabel, {0, 0}, 5); primaryLayout.append(regDBValue, {0, 0}); layout.append(secondaryLayout, {~0, 0}, 5); secondaryLayout.append(flagN, {0, 0}, 5); secondaryLayout.append(flagV, {0, 0}, 5); secondaryLayout.append(flagM, {0, 0}, 5); secondaryLayout.append(flagX, {0, 0}, 5); secondaryLayout.append(flagD, {0, 0}, 5); secondaryLayout.append(flagI, {0, 0}, 5); secondaryLayout.append(flagZ, {0, 0}, 5); secondaryLayout.append(flagC, {0, 0}); layout.append(tertiaryLayout, {~0, 0}); tertiaryLayout.append(flagE, {0, 0}, 5); tertiaryLayout.append(spacer, {~0, 0}); tertiaryLayout.append(update, {80, 0}); append(layout); update.onActivate = [&] { saveRegisters(); cpuDebugger->updateDisassembly(); setVisible(false); }; setGeometry({{128, 128}, layout.minimumGeometry().size()}); windowManager->append(this, "CPURegisterEditor"); }
/* * Execute the specified method. Return true if the method is executed, * false if it is rolled back for garbage collection. * * target: object for instance methods, class for static * method: the method to be run * offset: amount to increment program counter */ int executeMethod(Ref target, Ref method, int offset) { /* printf("["); if (method[ENTRY_FLAGS].i & ACC_STATIC) { debugString(target[TYPE_NAME].s); } else { debugString(method[ENTRY_OWNER].s[TYPE_NAME].s); } printf("."); debugString(method[ENTRY_NAME].s); debugString(method[ENTRY_DESCRIPTOR].s); printf("]\n"); */ // check for native method Int argcount = getInt(method, METHOD_ARG_COUNT); Int flags = getInt(method, ENTRY_FLAGS); if (flags & ACC_NATIVE) { return executeNativeMethod(target, method, offset); } // if synchronized, acquire the lock Ref lock = NULL; if (flags & ACC_SYNCHRONIZED) { lock = getLock(target); if (lock == NULL) { return FALSE; } // rollback, gc done acquireLock(thread, lock, 0); if (thread == NULL) { return FALSE; } // rollback, wait for lock } // allocate space for new frame Int maxLocals = getInt(method, METHOD_MAX_LOCALS); Int maxStack = getInt(method, METHOD_MAX_STACK); int numWords = FRAME_LOCALS + 2*maxLocals + 2*maxStack; Ref newFrame = allocate(numWords, HEADER_STACK_FRAME); if (newFrame == NULL) { return FALSE; } // rollback, gc done // increment lock count now that instruction can't be rolled back if (flags & ACC_SYNCHRONIZED) { Int count = getInt(lock, LOCK_COUNT); setInt(lock, LOCK_COUNT, count + 1); } // initialise new frame int hash = (char*) newFrame - (char*) core; Ref frameType = getRef(frame, OBJECT_TYPE); setInt(newFrame, OBJECT_HASHCODE, hash); setRef(newFrame, OBJECT_LOCK, lock); setRef(newFrame, OBJECT_TYPE, frameType); setRef(newFrame, FRAME_RETURN_FRAME, frame); setRef(newFrame, FRAME_METHOD, method); setInt(newFrame, FRAME_RETURN_PC, pc + offset); setInt(newFrame, FRAME_PC, 0); setInt(newFrame, FRAME_SP, numWords * 4); // pop arguments off current stack and write to new frame int index = argcount; while (--index >= 0) { if (refOnStack()) { setLocalRef(index, popRef(), newFrame); } else { setLocalInt(index, popInt(), newFrame); } } // point current thread to new frame saveRegisters(); setRef(thread, THREAD_FRAME, newFrame); loadRegisters(); return TRUE; }