extern "C" {
#include <machine/machine_routines.h>
}
#include <IOKit/pwr_mgt/RootDomain.h>
#include <IOKit/IODeviceTreeSupport.h>
#include "Gossamer.h"
#define super ApplePlatformExpert
OSDefineMetaClassAndStructors(GossamerPE, ApplePlatformExpert);
bool GossamerPE::start(IOService *provider)
{
unsigned int tmpVal;
long machineType;
long allInOne;
setChipSetType(kChipSetTypeGossamer);
if (IODTMatchNubWithKeys(provider, "'AAPL,Gossamer'"))
machineType = kGossamerTypeGossamer;
else if (IODTMatchNubWithKeys(provider, "'AAPL,PowerMac G3'"))
machineType = kGossamerTypeSilk;
else if (IODTMatchNubWithKeys(provider, "'AAPL,PowerBook1998'"))
machineType = kGossamerTypeWallstreet;
else if (IODTMatchNubWithKeys(provider, "'iMac,1'"))
machineType = kGossamerTypeiMac;
else if (IODTMatchNubWithKeys(provider, "('PowerMac1,1', 'PowerMac1,2')"))
machineType = kGossamerTypeYosemite;
else if (IODTMatchNubWithKeys(provider, "'PowerBook1,1'"))
machineType = kGossamerType101;
else return false;
setMachineType(machineType);
allInOne = 0;
if (ml_probe_read(kGossamerMachineIDReg, &tmpVal)) {
switch (getMachineType()) {
case kGossamerTypeGossamer :
case kGossamerTypeSilk :
if (!(tmpVal & kGossamerAllInOneMask)) allInOne = 1;
break;
case kGossamerTypeiMac :
allInOne = 1;
break;
}
}
if (allInOne) setProperty("AllInOne", this);
switch (getMachineType()) {
case kGossamerTypeGossamer:
case kGossamerTypeSilk:
case kGossamerTypeiMac:
case kGossamerTypeYosemite:
_pePMFeatures = kStdDesktopPMFeatures;
_pePrivPMFeatures = kStdDesktopPrivPMFeatures;
_peNumBatteriesSupported = kStdDesktopNumBatteries;
break;
case kGossamerTypeWallstreet:
_pePMFeatures = kWallstreetPMFeatures;
_pePrivPMFeatures = kWallstreetPrivPMFeatures;
_peNumBatteriesSupported = kStdPowerBookNumBatteries;
break;
case kGossamerType101:
_pePMFeatures = k101PMFeatures;
_pePrivPMFeatures = k101PrivPMFeatures;
_peNumBatteriesSupported = kStdPowerBookNumBatteries;
break;
}
return super::start(provider);
}
bool GossamerPE::platformAdjustService(IOService *service)
{
long tmpNum;
OSData *tmpData;
if (getProperty("AllInOne") &&
((getMachineType() == kGossamerTypeGossamer) ||
(getMachineType() == kGossamerTypeSilk))) {
if (!strcmp(service->getName(), "sound")) {
tmpNum = 3;
tmpData = OSData::withBytes(&tmpNum, sizeof(tmpNum));
if (tmpData) {
service->setProperty("#-detects", tmpData);
service->setProperty("#-outputs", tmpData);
tmpData->release();
}
return true;
}
}
if (getMachineType() == kGossamerTypeWallstreet) {
if (IODTMatchNubWithKeys(service, "('grackle', 'MOT,PPC106')")) {
service->setProperty("set-loop-snoop", service);
return true;
}
}
if (getMachineType() == kGossamerType101) {
if (!strcmp(service->getName(), "ATY,LTProParent")) {
if (kIOReturnSuccess == IONDRVLibrariesInitialize(service)) {
createNubs(this, service->getChildIterator( gIODTPlane ));
}
return true;
}
}
return true;
}
IOReturn GossamerPE::callPlatformFunction(const OSSymbol *functionName,
bool waitForFunction,
void *param1, void *param2,
void *param3, void *param4)
{
if (functionName == gGetDefaultBusSpeedsKey) {
getDefaultBusSpeeds((long *)param1, (unsigned long **)param2);
return kIOReturnSuccess;
}
return super::callPlatformFunction(functionName, waitForFunction,
param1, param2, param3, param4);
}
static unsigned long gossamerSpeed[] = { 66820000, 1 };
static unsigned long yosemiteSpeed[] = { 99730000, 1 };
void GossamerPE::getDefaultBusSpeeds(long *numSpeeds,
unsigned long **speedList)
{
if ((numSpeeds == 0) || (speedList == 0)) return;
switch (getMachineType()) {
case kGossamerTypeGossamer :
case kGossamerTypeSilk :
*numSpeeds = 1;
*speedList = gossamerSpeed;
break;
case kGossamerTypeYosemite :
*numSpeeds = 1;
*speedList = yosemiteSpeed;
break;
default :
*numSpeeds = 0;
*speedList = 0;
break;
}
}
void GossamerPE::PMInstantiatePowerDomains ( void )
{
root = new IOPMrootDomain;
root->init();
root->attach(this);
root->start(this);
root->youAreRoot();
root->setSleepSupported(kRootDomainSleepSupported);
}
void GossamerPE::PMRegisterDevice(IOService * theNub, IOService * theDevice)
{
while ((theNub != NULL) && ( theNub->addPowerChild(theDevice) != IOPMNoErr )) {
theNub = theNub->getProvider();
}
if ( theNub == NULL ) {
root->addPowerChild ( theDevice );
return;
}
}