/* * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * DRI: Josh de Cesare * */ extern "C" { #include } #include #include //#include #include "Gossamer.h" /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #define super ApplePlatformExpert OSDefineMetaClassAndStructors(GossamerPE, ApplePlatformExpert); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ bool GossamerPE::start(IOService *provider) { unsigned int tmpVal; long machineType; long allInOne; setChipSetType(kChipSetTypeGossamer); // Set the machine type. 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); // Find out if this an all in one. 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); // setup default power mgr features per machine // NOTE: on Core99 and later hardware, this information // is available from the "prim-info" property in the power-mgt // node of the device tree. Prior to that, this information // was just another hard-coded part of the ROM. 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; // Add the extra sound properties for Gossamer AIO 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; } } // Set the loop snoop property for Wallstreet or Mainstreet. if (getMachineType() == kGossamerTypeWallstreet) { if (IODTMatchNubWithKeys(service, "('grackle', 'MOT,PPC106')")) { // Add the property for set loop snoop. service->setProperty("set-loop-snoop", service); return true; } } // Publish out the dual display heads on 101. 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; } } //********************************************************************************* // PMInstantiatePowerDomains // // This overrides the vanilla implementation in IOPlatformExpert. It instantiates // a root domain with two children, one for the USB bus (to handle the USB idle // power budget), and one for the expansions slots on the PCI bus (to handle // the idle PCI power budget) //********************************************************************************* void GossamerPE::PMInstantiatePowerDomains ( void ) { root = new IOPMrootDomain; root->init(); root->attach(this); root->start(this); root->youAreRoot(); /* All G3s support sleep (or pseudo-sleep) now if ((getMachineType() == kGossamerType101) || (getMachineType() == kGossamerTypeWallstreet)) */ root->setSleepSupported(kRootDomainSleepSupported); } //********************************************************************************* // PMRegisterDevice // // This overrides the vanilla implementation in IOPlatformExpert. //********************************************************************************* //#define DONOTREGISTERATACONTROLLER 1 void GossamerPE::PMRegisterDevice(IOService * theNub, IOService * theDevice) { //#ifdef DONOTREGISTERATACONTROLLER // do not add IOATAStandardDriver to the tree since on this platform they do not need resets // if (OSDynamicCast(IOATAStandardDriver, theDevice) != NULL) // return; //#endif // Checks if the nub handles power states, if it does not gets its parent and so // up until we reach the root, or we do not find anything: while ((theNub != NULL) && ( theNub->addPowerChild(theDevice) != IOPMNoErr )) { theNub = theNub->getProvider(); //#ifdef DONOTREGISTERATACONTROLLER // IOATAStandardDriver are detached, and so would be evrething I attach to them so // their childs go directly on the tree. // if (OSDynamicCast(IOATAStandardDriver, theNub) != NULL) { // theNub = theNub->getProvider(); // } //#endif } if ( theNub == NULL ) { root->addPowerChild ( theDevice ); return; } }