#include <sys/cdefs.h>
__BEGIN_DECLS
#if defined( __ppc__ )
#include <ppc/proc_reg.h>
#endif
#include <machine/machine_routines.h>
__END_DECLS
#include <IOKit/IODeviceTreeSupport.h>
#include <IOKit/IOPlatformExpert.h>
#include <IOKit/IOCPU.h>
#include <IOKit/pci/IOPCIBridge.h>
#include <IOKit/pwr_mgt/RootDomain.h>
#include "MacRISC4CPU.h"
#define kMacRISC_GPIO_DIRECTION_BIT 2
#ifndef kIOHibernateStateKey
#define kIOHibernateStateKey "IOHibernateState"
#endif
#define super IOCPU
OSDefineMetaClassAndStructors(MacRISC4CPU, IOCPU);
#define kU3IIC "PPCI2CInterface.i2c-uni-n"
static const cpu_timebase_params_t cypress =
{ kU3IIC, 0x00, 0xD0, 0x81,
0x0C, 0x0C, 0x00 };
static const cpu_timebase_params_t pulsar =
{ kU3IIC, 0x00, 0xD4, 0x2E,
0x77, 0x22, 0x11 };
static const cpu_timebase_params_t pulsarD2 =
{ kU3IIC, 0x00, 0xD2, 0x2E,
0x77, 0x22, 0x11 };
static bool gI2CTransactionComplete;
static IOService *gI2CDriver,
*gTBDriver;
static const OSSymbol *gTBFunctionNameSym;
static const OSSymbol *gTBReadFunctionNameSym; static const cpu_timebase_params_t *gTimeBaseParams;
static UInt32 *gPHibernateState;
static IOCPUInterruptController *gCPUIC;
bool MacRISC4CPU::start(IOService *provider)
{
#if defined( __ppc__ )
kern_return_t result;
#endif
IORegistryEntry *cpusRegEntry, *cpu0RegEntry, *mpicRegEntry;
OSIterator *cpusIterator;
OSData *tmpData;
IOService *service;
const OSSymbol *interruptControllerName, *mpicICSymbol;
OSData *interruptData, *parentICData;
OSArray *tmpArray;
OSDictionary *matchDict;
char mpicICName[48];
bool makeInterruptsProperties;
UInt32 maxCPUs, physCPU, mpicPHandle;
IOService *tbResources;
ml_processor_info_t processor_info;
mpic_getProvider = OSSymbol::withCString("mpic_getProvider");
mpic_getIPIVector= OSSymbol::withCString("mpic_getIPIVector");
mpic_setCurrentTaskPriority = OSSymbol::withCString("mpic_setCurrentTaskPriority");
mpic_setUpForSleep = OSSymbol::withCString("mpic_setUpForSleep");
mpic_dispatchIPI = OSSymbol::withCString("mpic_dispatchIPI");
keyLargo_restoreRegisterState = OSSymbol::withCString("keyLargo_restoreRegisterState");
keyLargo_syncTimeBase = OSSymbol::withCString("keyLargo_syncTimeBase");
keyLargo_saveRegisterState = OSSymbol::withCString("keyLargo_saveRegisterState");
keyLargo_turnOffIO = OSSymbol::withCString("keyLargo_turnOffIO");
keyLargo_writeRegUInt8 = OSSymbol::withCString("keyLargo_writeRegUInt8");
keyLargo_setPowerSupply = OSSymbol::withCString("setPowerSupply");
UniNSetPowerState = OSSymbol::withCString("UniNSetPowerState");
UniNPrepareForSleep = OSSymbol::withCString("UniNPrepareForSleep");
i2c_openI2CBus = OSSymbol::withCString("openI2CBus");
i2c_closeI2CBus = OSSymbol::withCString("closeI2CBus");
i2c_setCombinedMode = OSSymbol::withCString("setCombinedMode");
i2c_setStandardSubMode = OSSymbol::withCString("setStandardSubMode");
i2c_readI2CBus = OSSymbol::withCString("readI2CBus");
i2c_writeI2CBus = OSSymbol::withCString("writeI2CBus");
u3APIPhyDisableProcessor1 = OSSymbol::withCString("u3APIPhyDisableProcessor1");
macRISC4PE = OSDynamicCast(MacRISC4PE, getPlatform());
if (macRISC4PE == 0) return false;
if (!super::start(provider)) return false;
tmpData = OSDynamicCast(OSData, provider->getProperty("state"));
if (tmpData == 0) return false;
bootCPU = (strcmp((char *)tmpData->getBytesNoCopy(), "running") == 0);
numCPUs = 0;
cpusRegEntry = fromPath("/cpus", gIODTPlane);
if (cpusRegEntry == 0) return false;
cpusIterator = cpusRegEntry->getChildIterator(gIODTPlane);
while (cpusIterator->getNextObject()) numCPUs++;
cpusIterator->release();
if ((numCPUs > 1) && !bootCPU)
(void) waitForService (resourceMatching ("BootCPU"));
if (PE_parse_boot_arg("cpus", &maxCPUs))
{
if (numCPUs > maxCPUs) numCPUs = maxCPUs;
}
if (numCPUs > 1 && (!(gTimeBaseParams || gTBDriver))) {
if (cpusRegEntry->getProperty ("platform-cpu-timebase")) {
OSData *pHandle;
char functionName[64];
if ((pHandle = OSDynamicCast( OSData, cpusRegEntry->getProperty("AAPL,phandle") )) != NULL) {
sprintf(functionName, "%s-%08lx", "platform-cpu-timebase", *((UInt32 *)pHandle->getBytesNoCopy()));
gTBFunctionNameSym = OSSymbol::withCString(functionName);
if (cpusRegEntry->getProperty ("platform-read-cpu-timebase")) {
sprintf(functionName, "%s-%08lx", "platform-read-cpu-timebase",
*((UInt32 *)pHandle->getBytesNoCopy()));
gTBReadFunctionNameSym = OSSymbol::withCString(functionName);
}
}
} else {
IORegistryEntry * clockchip;
if ((strcmp(macRISC4PE->provider_name, "PowerMac7,2") == 0) || (strcmp(macRISC4PE->provider_name, "PowerMac7,3") == 0)) {
if ((clockchip = fromPath("/u3/i2c/i2c-hwclock@d2", gIODTPlane, 0, 0, 0)) != NULL) {
OSString *pulsarCompat, *cypressCompat;
pulsarCompat = OSString::withCString ("pulsar-legacy-slewing");
cypressCompat = NULL;
if (IODTCompareNubName(clockchip, pulsarCompat, NULL)) {
gTimeBaseParams = &pulsarD2;
} else {
cypressCompat = OSString::withCString ("cy28508");
if (IODTCompareNubName(clockchip, cypressCompat, NULL)) {
gTimeBaseParams = &cypress;
}
}
pulsarCompat->release();
if (cypressCompat) cypressCompat->release();
} else if ((clockchip = fromPath("/u3/i2c/i2c-hwclock@d4", gIODTPlane, 0, 0, 0)) != NULL) {
gTimeBaseParams = &pulsar;
}
if (clockchip) clockchip->release();
}
else if (strcmp(macRISC4PE->provider_name, "RackMac3,1") == 0)
{
if ((clockchip = fromPath("/u3/i2c/i2c-hwclock@d4", gIODTPlane, 0, 0, 0)) != NULL)
{
clockchip->release();
gTimeBaseParams = &pulsar;
}
}
}
if (!(gTimeBaseParams || gTBFunctionNameSym)) {
IOLog("WARNING: don't know how to sync MP timebase, limiting to one CPU\n");
kprintf("WARNING: don't know how to sync MP timebase, limiting to one CPU\n");
numCPUs = 1;
}
}
doSleep = false;
flushOnLock = false;
cpu0RegEntry = fromPath("/cpus/@0", gIODTPlane);
if (cpu0RegEntry == 0) return false;
if (cpu0RegEntry->getProperty("flush-on-lock") != 0) flushOnLock = true;
tmpData = OSDynamicCast(OSData, provider->getProperty("reg"));
if (tmpData == 0) return false;
physCPU = *(long *)tmpData->getBytesNoCopy();
setCPUNumber(physCPU);
if (numCPUs > 1) {
tmpData = OSDynamicCast(OSData, provider->getProperty("soft-reset"));
if (tmpData == 0)
{
IOLog ("MacRISC4CPU::start - cpu(%ld) - no soft-reset property\n", physCPU);
return false;
} else
soft_reset_offset = *(long *)tmpData->getBytesNoCopy();
}
if (bootCPU)
{
gCPUIC = new IOCPUInterruptController;
if (gCPUIC == 0) return false;
if (gCPUIC->initCPUInterruptController(numCPUs) != kIOReturnSuccess)
return false;
gCPUIC->attach(this);
gCPUIC->registerCPUInterruptController();
}
tmpData = OSDynamicCast(OSData, provider->getProperty("l2cr"));
if (tmpData != 0)
l2crValue = *(long *)tmpData->getBytesNoCopy() & 0x7FFFFFFF;
#if defined( __ppc__ )
else
l2crValue = mfl2cr() & 0x7FFFFFFF;
#endif
keyLargo = waitForService(serviceMatching("KeyLargo"));
if (keyLargo == 0) return false;
if (tmpArray = OSDynamicCast (OSArray, (cpuNub->getProperty(gIOInterruptControllersKey)))) {
makeInterruptsProperties = false;
mpicICSymbol = OSSymbol::withString ((const OSString *)tmpArray->getObject(0));
} else {
makeInterruptsProperties = true;
parentICData = OSDynamicCast(OSData, provider->getProperty(kMacRISC4ParentICKey));
if (parentICData) {
mpicPHandle = *(UInt32 *)parentICData->getBytesNoCopy();
sprintf(mpicICName, "IOInterruptController%08lX", mpicPHandle);
mpicICSymbol = OSSymbol::withCString(mpicICName);
} else {
IOLog ("MacRISC4CPU::start - no cpu IOInterruptController! Start failed!\n");
return false;
}
}
matchDict = serviceMatching("AppleMPICInterruptController");
matchDict->setObject("InterruptControllerName", mpicICSymbol);
mpic = waitForService(matchDict);
if (makeInterruptsProperties) {
mpic->callPlatformFunction(mpic_getProvider, false, (void *)&mpicRegEntry, 0, 0, 0);
interruptControllerName = IODTInterruptControllerName(mpicRegEntry);
mpic->callPlatformFunction(mpic_getIPIVector, false, (void *)&physCPU, (void *)&interruptData, 0, 0);
if ((interruptControllerName == 0) || (interruptData == 0)) return false;
tmpArray = OSArray::withCapacity(1);
tmpArray->setObject(interruptControllerName);
cpuNub->setProperty(gIOInterruptControllersKey, tmpArray);
tmpArray->release();
tmpArray = OSArray::withCapacity(1);
tmpArray->setObject(interruptData);
cpuNub->setProperty(gIOInterruptSpecifiersKey, tmpArray);
tmpArray->release();
}
setCPUState(kIOCPUStateUninitalized);
service = waitForService(serviceMatching("IOPMrootDomain"));
pmRootDomain = OSDynamicCast(IOPMrootDomain, service);
if (pmRootDomain != 0)
{
kprintf("Register MacRISC4CPU %d to acknowledge power changes\n", getCPUNumber());
pmRootDomain->registerInterestedDriver(this);
PMinit();
provider->joinPMtree(this);
}
registerService();
if (!(uniN = waitForService(serviceMatching("AppleU3")))) return false;
if (numCPUs == 1)
uniN->callPlatformFunction (u3APIPhyDisableProcessor1, false, (void *)0, (void *)0, (void *)0, (void *)0);
if (numCPUs > 1) {
if (gTimeBaseParams && !gI2CDriver) {
tbResources = waitForService (resourceMatching ( gTimeBaseParams->i2c_iface ));
if (tbResources) {
gI2CDriver = OSDynamicCast (IOService, tbResources->getProperty ( gTimeBaseParams->i2c_iface ));
if (!gI2CDriver)
{
kprintf ("MacRISC4CPU::start(%ld) - failed i2cDriver\n", getCPUNumber());
return false;
}
}
} else if (gTBFunctionNameSym && !gTBDriver) {
#if 0
mach_timespec_t waitTimeout;
waitTimeout.tv_sec = 15;
waitTimeout.tv_nsec = 0;
tbResources = waitForService(resourceMatching(gTBFunctionNameSym), &waitTimeout);
#else
tbResources = waitForService(resourceMatching(gTBFunctionNameSym));
#endif
if (tbResources)
gTBDriver = OSDynamicCast (IOService, tbResources->getProperty(gTBFunctionNameSym));
}
}
if (bootCPU)
publishResource ("BootCPU", this);
if (physCPU < numCPUs)
{
processor_info.cpu_id = (cpu_id_t)this;
processor_info.boot_cpu = bootCPU;
processor_info.start_paddr = 0x0100;
processor_info.l2cr_value = l2crValue;
processor_info.supports_nap = !flushOnLock;
processor_info.time_base_enable = MacRISC4CPU::sEnableCPUTimeBase;
#if defined( __ppc__ )
OSData* powerTuneData;
if ( ( powerTuneData = OSDynamicCast( OSData, cpu0RegEntry->getProperty( "power-mode-data" ) ) ) != NULL )
{
uint32_t* powerTuneEntry;
powerTuneEntry = ( uint32_t * ) powerTuneData->getBytesNoCopy();
if ( powerTuneData->getLength() >= ( 2 * sizeof( uint32_t ) ) )
{
processor_info.power_mode_0 = powerTuneEntry[ 0 ];
processor_info.power_mode_1 = powerTuneEntry[ 1 ];
}
}
#endif
#if defined( __ppc__ )
kprintf("MacRISC4CPU::start(%ld) - registering with mach\n", getCPUNumber());
result = ml_processor_register(&processor_info, &machProcessor, &ipi_handler);
if (result == KERN_FAILURE) return false;
#endif
processor_start(machProcessor);
}
if (!pmu) {
service = waitForService(resourceMatching("IOPMU"));
if (service)
if (!(pmu = OSDynamicCast (IOService, service->getProperty("IOPMU")))) return false;
}
uniN->callPlatformFunction ("setupUATAforSleep", false, (void *)0, (void *)0, (void *)0, (void *)0);
if (cpusRegEntry) cpusRegEntry->release();
if (cpu0RegEntry) cpu0RegEntry->release();
kprintf ("MacRISC4CPU::start(%ld) - done\n", getCPUNumber());
return true;
}
void MacRISC4CPU::initCPU(bool boot)
{
IOPCIBridge *pciDriver;
UInt32 i;
if (!boot && bootCPU) {
uniN->callPlatformFunction (UniNSetPowerState, false, (void *)kUniNNormal,
(void *)0, (void *)0, (void *)0);
if (numCPUs == 1)
uniN->callPlatformFunction (u3APIPhyDisableProcessor1, false, (void *)0, (void *)0, (void *)0, (void *)0);
if (!processorSpeedChange) {
for (i = 0; i < topLevelPCIBridgeCount; i++)
if (pciDriver = topLevelPCIBridges[i])
pciDriver->setDevicePowerState (NULL, 3);
keyLargo->callPlatformFunction(keyLargo_restoreRegisterState, false, 0, 0, 0, 0);
if (macRISC4PE->getMachineType() == kMacRISC4TypePowerMac) {
haveSleptMPIC = false;
kprintf("MacRISC4CPU::initCPU %d -> mpic->setUpForSleep off", getCPUNumber());
mpic->callPlatformFunction(mpic_setUpForSleep, false, (void *)false, (void *)getCPUNumber(), 0, 0);
}
}
}
kprintf("MacRISC4CPU::initCPU %d Here!\n", getCPUNumber());
if (bootCPU)
keyLargo->callPlatformFunction(keyLargo_syncTimeBase, false, 0, 0, 0, 0);
if (boot) {
if (gCPUIC)
gCPUIC->enableCPUInterrupt(this);
else
panic ("MacRISC4CPU: gCPUIC uninitialized for CPU %d\n", getCPUNumber());
cpuNub->registerInterrupt(0, this, MacRISC4CPU::sIPIHandler, 0);
cpuNub->enableInterrupt(0);
} else {
long priority = 0;
mpic->callPlatformFunction(mpic_setCurrentTaskPriority, false, (void *)&priority, 0, 0, 0);
}
setCPUState(kIOCPUStateRunning);
kprintf ("MacRISC4CPU::initCPU(%ld) - done\n", getCPUNumber());
return;
}
void MacRISC4CPU::quiesceCPU(void)
{
if (bootCPU)
{
uniN->callPlatformFunction (UniNSetPowerState, false, (void *)(kUniNSave),
(void *)0, (void *)0, (void *)0);
if (!gPHibernateState || !*gPHibernateState) {
uniN->callPlatformFunction (UniNSetPowerState, false, (void *)(kUniNSleep),
(void *)0, (void *)0, (void *)0);
}
if (processorSpeedChange) {
pmu->callPlatformFunction("setSpeedNow", false, (void *)currentProcessorSpeed, 0, 0, 0);
} else {
if (!gPHibernateState || !*gPHibernateState)
pmu->callPlatformFunction("sleepNow", false, 0, 0, 0, 0);
if (!haveSleptMPIC && (macRISC4PE->getMachineType() == kMacRISC4TypePowerMac))
{
haveSleptMPIC = true;
mpic->callPlatformFunction(mpic_setUpForSleep, false, (void *)true, (void *)getCPUNumber(), 0, 0);
}
keyLargo->callPlatformFunction(keyLargo_saveRegisterState, false, 0, 0, 0, 0);
if (!gPHibernateState || !*gPHibernateState) {
keyLargo->callPlatformFunction(keyLargo_turnOffIO, false, (void *)false, 0, 0, 0);
}
}
ml_phys_write(0x0080, 0x100);
}
#if defined( __ppc__ )
ml_ppc_sleep();
#endif
return;
}
kern_return_t MacRISC4CPU::startCPU(vm_offset_t , vm_offset_t )
{
long gpioOffset = soft_reset_offset;
unsigned long strobe_value;
if (!(gTimeBaseParams || gTBDriver))
{
IOLog("MacRISC4CPU::startCPU(%ld) - cannot manage timebase synchronization\n", getCPUNumber() );
return KERN_FAILURE;
}
if (gTimeBaseParams) {
gI2CTransactionComplete = false;
if (gI2CDriver && (kIOReturnSuccess == gI2CDriver->callPlatformFunction (i2c_openI2CBus, false,
(void *) (UInt32)gTimeBaseParams->i2c_port, (void *) 0, (void *) 0, (void *) 0))) {
kprintf ("MacRISC4CPU::startCPU(%ld) i2c bus opened\n", getCPUNumber());
}
}
strobe_value = ( 1 << kMacRISC_GPIO_DIRECTION_BIT );
keyLargo->callPlatformFunction(keyLargo_writeRegUInt8, false,
(void *)&gpioOffset, (void *)strobe_value, 0, 0);
strobe_value = ( 0 << kMacRISC_GPIO_DIRECTION_BIT );
keyLargo->callPlatformFunction(keyLargo_writeRegUInt8, false,
(void *)&gpioOffset, (void *)strobe_value, 0, 0);
if (gTimeBaseParams) {
while (!gI2CTransactionComplete) IOSleep (10);
gI2CDriver->callPlatformFunction (i2c_closeI2CBus, false, (void *) 0, (void *) 0, (void *) 0, (void *) 0);
kprintf ("MacRISC4CPU::startCPU(%ld) i2c bus closed\n", getCPUNumber());
}
return KERN_SUCCESS;
}
void MacRISC4CPU::haltCPU(void)
{
OSIterator *childIterator;
IORegistryEntry *childEntry, *childDriver;
IOPCIBridge *pciDriver;
OSData *deviceTypeString;
UInt32 i;
setCPUState(kIOCPUStateStopped);
if (bootCPU)
{
if (!gPHibernateState) {
OSData * data = OSDynamicCast(OSData, getPMRootDomain()->getProperty(kIOHibernateStateKey));
if (data)
gPHibernateState = (UInt32 *) data->getBytesNoCopy();
}
uniN->callPlatformFunction (UniNPrepareForSleep, false,
(void *)0, (void *)0, (void *)0, (void *)0);
if (!topLevelPCIBridgeCount) {
if ((childIterator = macRISC4PE->getChildIterator (gIOServicePlane)) != NULL) {
while ((childEntry = (IORegistryEntry *)(childIterator->getNextObject ())) != NULL) {
deviceTypeString = OSDynamicCast( OSData, childEntry->getProperty( "device_type" ));
if (deviceTypeString) {
if (!strcmp((const char *)deviceTypeString->getBytesNoCopy(), "pci")) {
childDriver = childEntry->copyChildEntry(gIOServicePlane);
if (childDriver) {
pciDriver = OSDynamicCast( IOPCIBridge, childDriver );
if (pciDriver)
if (topLevelPCIBridgeCount < kMaxPCIBridges)
topLevelPCIBridges[topLevelPCIBridgeCount++] = pciDriver;
else
kprintf ("MacRISC4CPU::haltCPU - warning, more than %ld PCI bridges - cannot save/restore them all\n", kMaxPCIBridges);
childDriver->release();
}
}
}
}
childIterator->release();
}
}
for (i = 0; i < topLevelPCIBridgeCount; i++)
if (pciDriver = topLevelPCIBridges[i]) {
pciDriver->setDevicePowerState (NULL, 2);
}
}
kprintf("MacRISC4CPU::haltCPU %d Here!\n", getCPUNumber());
processor_exit(machProcessor);
return;
}
void MacRISC4CPU::signalCPU(IOCPU *target)
{
UInt32 physCPU = getCPUNumber();
MacRISC4CPU *targetCPU = OSDynamicCast(MacRISC4CPU, target);
if (targetCPU == 0) return;
mpic->callPlatformFunction(mpic_dispatchIPI, false, (void *)&physCPU, (void *)(1 << targetCPU->getCPUNumber()), 0, 0);
return;
}
void MacRISC4CPU::sEnableCPUTimeBase( cpu_id_t self, boolean_t enable )
{
MacRISC4CPU* pe = ( MacRISC4CPU * ) self;
pe->enableCPUTimeBase( enable );
}
#if 0
static void getCPUTimebase (UInt32 *tbuRet, UInt32 *tblRet)
{
UInt32 tbu, tbu2, tbl;
do {
asm volatile(" mftbu %0" : "=r" (tbu));
asm volatile(" mftb %0" : "=r" (tbl));
asm volatile(" mftbu %0" : "=r" (tbu2));
} while (tbu != tbu2);
*tbuRet = tbu;
*tblRet = tbl;
return;
}
#endif
void MacRISC4CPU::enableCPUTimeBase(bool enable)
{
if (gTBDriver) {
UInt32 gpioValue;
UInt32 count = 0;
if (gTBReadFunctionNameSym)
gpioValue = 0;
else
gpioValue = enable ? 1 : 0;
gTBDriver->callPlatformFunction (gTBFunctionNameSym, false, (void *)gpioValue, 0, 0, 0);
if (gTBReadFunctionNameSym) {
UInt32 gpioState;
do {
count++;
gTBDriver->callPlatformFunction (gTBReadFunctionNameSym, false, (void *)&gpioState, 0, 0, 0);
} while ((gpioState == 0) && (count < 15));
kprintf ("MacRISC4CPU::enableCPUTimeBase(%s) complete\n", enable ? "enable" : "disable");
}
} else {
UInt8 sevenBitAddr, buf, tmp;
gI2CDriver->callPlatformFunction (i2c_setCombinedMode, false, (void *) 0, (void *) 0, (void *) 0, (void *) 0);
sevenBitAddr = gTimeBaseParams->i2c_addr >> 1;
if (kIOReturnSuccess == gI2CDriver->callPlatformFunction (i2c_readI2CBus, false, (void *)(UInt32)sevenBitAddr, (void *) (UInt32)gTimeBaseParams->i2c_subaddr, (void *)(UInt32)&buf, (void *)1)) {
tmp = enable ? gTimeBaseParams->enable_value : gTimeBaseParams->disable_value;
buf = (buf & ~gTimeBaseParams->mask) | (tmp & gTimeBaseParams->mask);
gI2CDriver->callPlatformFunction (i2c_setStandardSubMode, false, (void *)0,(void *) 0, (void *)0, (void *)0);
gI2CDriver->callPlatformFunction (i2c_writeI2CBus, false, (void *)(UInt32)sevenBitAddr,(void *) (UInt32)gTimeBaseParams->i2c_subaddr, (void *)(UInt32)& buf, (void *)1);
} else {
kprintf ("MacRISC4CPU::enableCPUTimeBase - I2C read failed\n");
return;
}
gI2CTransactionComplete = enable;
kprintf ("MacRISC4CPU::enableCPUTimeBase(%s) - I2C transaction complete\n", enable ? "enable" : "disable");
}
return;
}
void MacRISC4CPU::sIPIHandler( OSObject* self, void* refCon, IOService* nub, int source )
{
MacRISC4CPU* pe = ( MacRISC4CPU * ) self;
pe->ipiHandler( refCon, nub, source );
}
void MacRISC4CPU::ipiHandler(void *refCon, void *nub, int source)
{
if (ipi_handler) ipi_handler();
return;
}
const OSSymbol *MacRISC4CPU::getCPUName(void)
{
char tmpStr[256];
sprintf(tmpStr, "Primary%ld", getCPUNumber());
return OSSymbol::withCString(tmpStr);
}