2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
26 #include <IOKit/system.h>
27 #include <IOKit/IOPlatformExpert.h>
28 #include <IOKit/IOCPU.h>
29 #include <IOKit/IODeviceTreeSupport.h>
30 #include <IOKit/IORangeAllocator.h>
31 #include <IOKit/IONVRAM.h>
32 #include <IOKit/IOKitDebug.h>
33 #include <IOKit/IOWorkLoop.h>
34 #include <IOKit/pwr_mgt/RootDomain.h>
36 #include <libkern/c++/OSContainers.h>
40 #include <machine/machine_routines.h>
41 #include <pexpert/pexpert.h>
44 void printDictionaryKeys (OSDictionary
* inDictionary
, char * inMsg
);
45 static void getCStringForObject (OSObject
* inObj
, char * outStr
);
47 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
49 #define super IOService
51 OSDefineMetaClassAndStructors(IOPlatformExpert
, IOService
)
53 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 0);
54 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 1);
55 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 2);
56 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 3);
57 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 4);
58 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 5);
59 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 6);
60 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 7);
61 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 8);
62 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 9);
63 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 10);
64 OSMetaClassDefineReservedUnused(IOPlatformExpert
, 11);
66 static IOPlatformExpert
* gIOPlatform
;
68 OSSymbol
* gPlatformInterruptControllerName
;
70 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
72 bool IOPlatformExpert::attach( IOService
* provider
)
75 if( !super::attach( provider
))
81 bool IOPlatformExpert::start( IOService
* provider
)
83 IORangeAllocator
* physicalRanges
;
84 OSData
* busFrequency
;
86 if (!super::start(provider
))
89 // Correct the bus frequency in the device tree.
90 busFrequency
= OSData::withBytesNoCopy((void *)&gPEClockFrequencyInfo
.bus_clock_rate_hz
, 4);
91 provider
->setProperty("clock-frequency", busFrequency
);
92 busFrequency
->release();
94 gPlatformInterruptControllerName
= (OSSymbol
*)OSSymbol::withCStringNoCopy("IOPlatformInterruptController");
96 physicalRanges
= IORangeAllocator::withRange(0xffffffff, 1, 16,
97 IORangeAllocator::kLocking
);
98 assert(physicalRanges
);
99 setProperty("Platform Memory Ranges", physicalRanges
);
104 PMInstantiatePowerDomains();
106 return( configure(provider
) );
109 bool IOPlatformExpert::configure( IOService
* provider
)
115 topLevel
= OSDynamicCast( OSSet
, getProperty("top-level"));
118 while( (dict
= OSDynamicCast( OSDictionary
,
119 topLevel
->getAnyObject()))) {
121 topLevel
->removeObject( dict
);
122 nub
= createNub( dict
);
127 nub
->registerService();
134 IOService
* IOPlatformExpert::createNub( OSDictionary
* from
)
138 nub
= new IOPlatformDevice
;
140 if( !nub
->init( from
)) {
148 bool IOPlatformExpert::compareNubName( const IOService
* nub
,
149 OSString
* name
, OSString
** matched
= 0 ) const
151 return( nub
->IORegistryEntry::compareName( name
, matched
));
154 IOReturn
IOPlatformExpert::getNubResources( IOService
* nub
)
156 return( kIOReturnSuccess
);
159 long IOPlatformExpert::getBootROMType(void)
161 return _peBootROMType
;
164 long IOPlatformExpert::getChipSetType(void)
166 return _peChipSetType
;
169 long IOPlatformExpert::getMachineType(void)
171 return _peMachineType
;
174 void IOPlatformExpert::setBootROMType(long peBootROMType
)
176 _peBootROMType
= peBootROMType
;
179 void IOPlatformExpert::setChipSetType(long peChipSetType
)
181 _peChipSetType
= peChipSetType
;
184 void IOPlatformExpert::setMachineType(long peMachineType
)
186 _peMachineType
= peMachineType
;
189 bool IOPlatformExpert::getMachineName( char * /*name*/, int /*maxLength*/)
194 bool IOPlatformExpert::getModelName( char * /*name*/, int /*maxLength*/)
199 IORangeAllocator
* IOPlatformExpert::getPhysicalRangeAllocator(void)
201 return(OSDynamicCast(IORangeAllocator
,
202 getProperty("Platform Memory Ranges")));
205 int (*PE_halt_restart
)(unsigned int type
) = 0;
207 int IOPlatformExpert::haltRestart(unsigned int type
)
209 if (PE_halt_restart
) return (*PE_halt_restart
)(type
);
213 void IOPlatformExpert::sleepKernel(void)
219 intState
= ml_set_interrupts_enabled(false);
221 for (cnt
= 0; cnt
< 10000; cnt
++) {
225 ml_set_interrupts_enabled(intState
);
227 // PE_initialize_console(0, kPEDisableScreen);
231 // PE_initialize_console(0, kPEEnableScreen);
235 long IOPlatformExpert::getGMTTimeOfDay(void)
240 void IOPlatformExpert::setGMTTimeOfDay(long secs
)
245 IOReturn
IOPlatformExpert::getConsoleInfo( PE_Video
* consoleInfo
)
247 return( PE_current_console( consoleInfo
));
250 IOReturn
IOPlatformExpert::setConsoleInfo( PE_Video
* consoleInfo
,
253 return( PE_initialize_console( consoleInfo
, op
));
256 IOReturn
IOPlatformExpert::registerInterruptController(OSSymbol
*name
, IOInterruptController
*interruptController
)
258 publishResource(name
, interruptController
);
260 return kIOReturnSuccess
;
263 IOInterruptController
*IOPlatformExpert::lookUpInterruptController(OSSymbol
*name
)
265 IOInterruptController
*interruptController
;
268 service
= waitForService(resourceMatching(name
));
270 interruptController
= OSDynamicCast(IOInterruptController
, service
->getProperty(name
));
272 return interruptController
;
276 void IOPlatformExpert::setCPUInterruptProperties(IOService
*service
)
278 IOCPUInterruptController
*controller
;
280 controller
= OSDynamicCast(IOCPUInterruptController
, waitForService(serviceMatching("IOCPUInterruptController")));
281 if (controller
) controller
->setCPUInterruptProperties(service
);
284 bool IOPlatformExpert::atInterruptLevel(void)
286 return ml_at_interrupt_context();
289 bool IOPlatformExpert::platformAdjustService(IOService */
*service*/
)
295 //*********************************************************************************
298 //*********************************************************************************
300 void IOPlatformExpert::PMLog(const char * who
,unsigned long event
,unsigned long param1
, unsigned long param2
)
302 if( gIOKitDebug
& kIOLogPower
) {
303 kprintf("%s %02d %08x %08x\n",who
,event
,param1
,param2
);
304 // IOLog("%s %02d %08x %08x\n",who,event,param1,param2);
309 //*********************************************************************************
310 // PMInstantiatePowerDomains
312 // In this vanilla implementation, a Root Power Domain is instantiated.
313 // All other objects which register will be children of this Root.
314 // Where this is inappropriate, PMInstantiatePowerDomains is overridden
315 // in a platform-specific subclass.
316 //*********************************************************************************
318 void IOPlatformExpert::PMInstantiatePowerDomains ( void )
320 root
= new IOPMrootDomain
;
328 //*********************************************************************************
331 // In this vanilla implementation, all callers are made children of the root power domain.
332 // Where this is inappropriate, PMRegisterDevice is overridden in a platform-specific subclass.
333 //*********************************************************************************
335 void IOPlatformExpert::PMRegisterDevice(IOService
* theNub
, IOService
* theDevice
)
337 root
->addPowerChild ( theDevice
);
340 //*********************************************************************************
343 //*********************************************************************************
345 bool IOPlatformExpert::hasPMFeature (unsigned long featureMask
)
347 return ((_pePMFeatures
& featureMask
) != 0);
350 //*********************************************************************************
353 //*********************************************************************************
355 bool IOPlatformExpert::hasPrivPMFeature (unsigned long privFeatureMask
)
357 return ((_pePrivPMFeatures
& privFeatureMask
) != 0);
360 //*********************************************************************************
361 // numBatteriesSupported
363 //*********************************************************************************
365 int IOPlatformExpert::numBatteriesSupported (void)
367 return (_peNumBatteriesSupported
);
370 //*********************************************************************************
373 // This method is called by the instantiated sublass of the platform expert to
374 // determine how a device should be inserted into the Power Domain. The subclass
375 // provides an XML power tree description against which a device is matched based
376 // on class and provider. If a match is found this routine returns true in addition
377 // to flagging the description tree at the appropriate node that a device has been
378 // registered for the given service.
379 //*********************************************************************************
381 bool IOPlatformExpert::CheckSubTree (OSArray
* inSubTree
, IOService
* theNub
, IOService
* theDevice
, OSDictionary
* theParent
)
384 unsigned int numPowerTreeNodes
;
385 OSDictionary
* entry
;
386 OSDictionary
* matchingDictionary
;
387 OSDictionary
* providerDictionary
;
388 OSDictionary
* deviceDictionary
;
389 OSDictionary
* nubDictionary
;
391 bool nodeFound
= false;
392 bool continueSearch
= false;
393 bool deviceMatch
= false;
394 bool providerMatch
= false;
395 bool multiParentMatch
= false;
397 if ( (NULL
== theDevice
) || (NULL
== inSubTree
) )
400 numPowerTreeNodes
= inSubTree
->getCount ();
402 // iterate through the power tree to find a home for this device
404 for ( i
= 0; i
< numPowerTreeNodes
; i
++ ) {
406 entry
= (OSDictionary
*) inSubTree
->getObject (i
);
408 matchingDictionary
= (OSDictionary
*) entry
->getObject ("device");
409 providerDictionary
= (OSDictionary
*) entry
->getObject ("provider");
411 deviceMatch
= true; // if no matching dictionary, this is not a criteria and so must match
412 if ( matchingDictionary
) {
414 if ( NULL
!= (deviceDictionary
= theDevice
->dictionaryWithProperties ())) {
415 deviceMatch
= deviceDictionary
->isEqualTo ( matchingDictionary
, matchingDictionary
);
416 deviceDictionary
->release ();
420 providerMatch
= true; // we indicate a match if there is no nub or provider
421 if ( theNub
&& providerDictionary
) {
422 providerMatch
= false;
423 if ( NULL
!= (nubDictionary
= theNub
->dictionaryWithProperties ()) ) {
424 providerMatch
= nubDictionary
->isEqualTo ( providerDictionary
, providerDictionary
);
425 nubDictionary
->release ();
429 multiParentMatch
= true; // again we indicate a match if there is no multi-parent node
430 if (deviceMatch
&& providerMatch
) {
431 if (NULL
!= multipleParentKeyValue
) {
432 OSNumber
* aNumber
= (OSNumber
*) entry
->getObject ("multiple-parent");
433 multiParentMatch
= (NULL
!= aNumber
) ? multipleParentKeyValue
->isEqualTo (aNumber
) : false;
437 nodeFound
= (deviceMatch
&& providerMatch
&& multiParentMatch
);
439 // if the power tree specifies a provider dictionary but theNub is
440 // NULL then we cannot match with this entry.
442 if ( theNub
== NULL
&& providerDictionary
!= NULL
)
445 // if this node is THE ONE...then register the device
448 if (RegisterServiceInTree (theDevice
, entry
, theParent
, theNub
) ) {
450 if ( kIOLogPower
& gIOKitDebug
)
451 IOLog ("PMRegisterDevice/CheckSubTree - service registered!\n");
453 numInstancesRegistered
++;
455 // determine if we need to search for additional nodes for this item
456 multipleParentKeyValue
= (OSNumber
*) entry
->getObject ("multiple-parent");
462 continueSearch
= ( (false == nodeFound
) || (NULL
!= multipleParentKeyValue
) );
464 if ( continueSearch
&& (NULL
!= (children
= (OSArray
*) entry
->getObject ("children"))) ) {
465 nodeFound
= CheckSubTree ( children
, theNub
, theDevice
, entry
);
466 continueSearch
= ( (false == nodeFound
) || (NULL
!= multipleParentKeyValue
) );
469 if ( false == continueSearch
)
473 return ( nodeFound
);
476 //*********************************************************************************
477 // RegisterServiceInTree
479 // Register a device at the specified node of our power tree.
480 //*********************************************************************************
482 bool IOPlatformExpert::RegisterServiceInTree (IOService
* theService
, OSDictionary
* theTreeNode
, OSDictionary
* theTreeParentNode
, IOService
* theProvider
)
484 IOService
* aService
;
485 bool registered
= false;
487 unsigned int numChildren
;
488 OSDictionary
* child
;
490 // make sure someone is not already registered here
492 if ( NULL
== theTreeNode
->getObject ("service") ) {
494 if ( theTreeNode
->setObject ("service", OSDynamicCast ( OSObject
, theService
)) ) {
496 // 1. CHILDREN ------------------
498 // we registered the node in the tree...now if the node has children
499 // registered we must tell this service to add them.
501 if ( NULL
!= (children
= (OSArray
*) theTreeNode
->getObject ("children")) ) {
502 numChildren
= children
->getCount ();
503 for ( unsigned int i
= 0; i
< numChildren
; i
++ ) {
504 if ( NULL
!= (child
= (OSDictionary
*) children
->getObject (i
)) ) {
505 if ( NULL
!= (aService
= (IOService
*) child
->getObject ("service")) )
506 theService
->addPowerChild (aService
);
511 // 2. PARENT --------------------
513 // also we must notify the parent of this node (if a registered service
514 // exists there) of a new child.
516 if ( theTreeParentNode
) {
517 if ( NULL
!= (aService
= (IOService
*) theTreeParentNode
->getObject ("service")) )
518 if (aService
!= theProvider
)
519 aService
->addPowerChild (theService
);
529 //*********************************************************************************
530 // printDictionaryKeys
532 // Print the keys for the given dictionary and selected contents.
533 //*********************************************************************************
534 void printDictionaryKeys (OSDictionary
* inDictionary
, char * inMsg
)
536 OSCollectionIterator
* mcoll
= OSCollectionIterator::withCollection (inDictionary
);
543 mkey
= OSDynamicCast (OSSymbol
, mcoll
->getNextObject ());
547 // kprintf ("dictionary key #%d: %s\n", i, mkey->getCStringNoCopy () );
549 // if this is the IOClass key, print it's contents
551 if ( mkey
->isEqualTo ("IOClass") ) {
552 ioClass
= (OSString
*) inDictionary
->getObject ("IOClass");
553 if ( ioClass
) IOLog ("%s IOClass is %s\n", inMsg
, ioClass
->getCStringNoCopy () );
556 // if this is an IOProviderClass key print it
558 if ( mkey
->isEqualTo ("IOProviderClass") ) {
559 ioClass
= (OSString
*) inDictionary
->getObject ("IOProviderClass");
560 if ( ioClass
) IOLog ("%s IOProviderClass is %s\n", inMsg
, ioClass
->getCStringNoCopy () );
564 // also print IONameMatch keys
565 if ( mkey
->isEqualTo ("IONameMatch") ) {
566 ioClass
= (OSString
*) inDictionary
->getObject ("IONameMatch");
567 if ( ioClass
) IOLog ("%s IONameMatch is %s\n", inMsg
, ioClass
->getCStringNoCopy () );
570 // also print IONameMatched keys
572 if ( mkey
->isEqualTo ("IONameMatched") ) {
573 ioClass
= (OSString
*) inDictionary
->getObject ("IONameMatched");
574 if ( ioClass
) IOLog ("%s IONameMatched is %s\n", inMsg
, ioClass
->getCStringNoCopy () );
580 if ( mkey
->isEqualTo ("AAPL,clock-id") ) {
582 cstr
= getCStringForObject (inDictionary
->getObject ("AAPL,clock-id"));
584 kprintf (" ===> AAPL,clock-id is %s\n", cstr
);
590 if ( mkey
->isEqualTo ("name") ) {
593 getCStringForObject (inDictionary
->getObject ("name"), nameStr
);
594 if (strlen(nameStr
) > 0)
595 IOLog ("%s name is %s\n", inMsg
, nameStr
);
598 mkey
= (OSSymbol
*) mcoll
->getNextObject ();
606 static void getCStringForObject (OSObject
* inObj
, char * outStr
)
611 if ( (NULL
== inObj
) || (NULL
== outStr
))
614 char * objString
= (char *) (inObj
->getMetaClass())->getClassName();
616 if ((0 == strcmp(objString
,"OSString")) || (0 == strcmp (objString
, "OSSymbol")))
617 strcpy (outStr
, ((OSString
*)inObj
)->getCStringNoCopy());
619 else if (0 == strcmp(objString
,"OSData")) {
620 len
= ((OSData
*)inObj
)->getLength();
621 buffer
= (char *)((OSData
*)inObj
)->getBytesNoCopy();
622 if (buffer
&& (len
> 0)) {
623 for (i
=0; i
< len
; i
++) {
624 outStr
[i
] = buffer
[i
];
634 * Callouts from BSD for machine name & model
637 boolean_t
PEGetMachineName( char * name
, int maxLength
)
640 return( gIOPlatform
->getMachineName( name
, maxLength
));
645 boolean_t
PEGetModelName( char * name
, int maxLength
)
648 return( gIOPlatform
->getModelName( name
, maxLength
));
653 int PEGetPlatformEpoch(void)
656 return( gIOPlatform
->getBootROMType());
661 int PEHaltRestart(unsigned int type
)
663 if (gIOPlatform
) return gIOPlatform
->haltRestart(type
);
667 long PEGetGMTTimeOfDay(void)
670 return( gIOPlatform
->getGMTTimeOfDay());
675 void PESetGMTTimeOfDay(long secs
)
678 gIOPlatform
->setGMTTimeOfDay(secs
);
683 void IOPlatformExpert::registerNVRAMController(IONVRAMController
* caller
)
685 publishResource("IONVRAM");
688 IOReturn
IOPlatformExpert::callPlatformFunction(const OSSymbol
*functionName
,
689 bool waitForFunction
,
690 void *param1
, void *param2
,
691 void *param3
, void *param4
)
693 IOService
*service
, *_resources
;
695 if (waitForFunction
) {
696 _resources
= waitForService(resourceMatching(functionName
));
698 _resources
= resources();
700 if (_resources
== 0) return kIOReturnUnsupported
;
702 service
= OSDynamicCast(IOService
, _resources
->getProperty(functionName
));
703 if (service
== 0) return kIOReturnUnsupported
;
705 return service
->callPlatformFunction(functionName
, waitForFunction
,
706 param1
, param2
, param3
, param4
);
710 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
713 #define super IOPlatformExpert
715 OSDefineMetaClassAndAbstractStructors( IODTPlatformExpert
, IOPlatformExpert
)
717 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 0);
718 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 1);
719 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 2);
720 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 3);
721 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 4);
722 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 5);
723 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 6);
724 OSMetaClassDefineReservedUnused(IODTPlatformExpert
, 7);
726 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
728 IOService
* IODTPlatformExpert::probe( IOService
* provider
,
731 if( !super::probe( provider
, score
))
734 // check machine types
735 if( !provider
->compareNames( getProperty( gIONameMatchKey
) ))
741 bool IODTPlatformExpert::configure( IOService
* provider
)
743 if( !super::configure( provider
))
746 processTopLevel( provider
);
751 IOService
* IODTPlatformExpert::createNub( IORegistryEntry
* from
)
755 nub
= new IOPlatformDevice
;
757 if( !nub
->init( from
, gIODTPlane
)) {
765 bool IODTPlatformExpert::createNubs( IOService
* parent
, OSIterator
* iter
)
767 IORegistryEntry
* next
;
772 while( (next
= (IORegistryEntry
*) iter
->getNextObject())) {
774 if( 0 == (nub
= createNub( next
)))
777 nub
->attach( parent
);
778 nub
->registerService();
786 void IODTPlatformExpert::processTopLevel( IORegistryEntry
* root
)
789 IORegistryEntry
* next
;
790 IORegistryEntry
* cpus
;
791 IORegistryEntry
* options
;
794 kids
= IODTFindMatchingEntries( root
, 0, deleteList() );
796 while( (next
= (IORegistryEntry
*)kids
->getNextObject())) {
797 next
->detachAll( gIODTPlane
);
802 // Publish an IODTNVRAM class on /options.
803 options
= root
->childFromPath("options", gIODTPlane
);
805 dtNVRAM
= new IODTNVRAM
;
807 if (!dtNVRAM
->init(options
, gIODTPlane
)) {
811 dtNVRAM
->attach(this);
812 dtNVRAM
->registerService();
818 cpus
= root
->childFromPath( "cpus", gIODTPlane
);
820 createNubs( this, IODTFindMatchingEntries( cpus
, kIODTExclusive
, 0));
822 // publish top level, minus excludeList
823 createNubs( this, IODTFindMatchingEntries( root
, kIODTExclusive
, excludeList()));
826 IOReturn
IODTPlatformExpert::getNubResources( IOService
* nub
)
828 if( nub
->getDeviceMemory())
829 return( kIOReturnSuccess
);
831 IODTResolveAddressing( nub
, "reg", 0);
833 return( kIOReturnSuccess
);
836 bool IODTPlatformExpert::compareNubName( const IOService
* nub
,
837 OSString
* name
, OSString
** matched
) const
839 return( IODTCompareNubName( nub
, name
, matched
)
840 || super::compareNubName( nub
, name
, matched
) );
843 bool IODTPlatformExpert::getModelName( char * name
, int maxLength
)
853 prop
= (OSData
*) getProvider()->getProperty( gIODTCompatibleKey
);
855 str
= (const char *) prop
->getBytesNoCopy();
857 if( 0 == strncmp( str
, "AAPL,", strlen( "AAPL," ) ))
858 str
+= strlen( "AAPL," );
861 while( (c
= *str
++)) {
862 if( (c
== '/') || (c
== ' '))
866 if( len
>= maxLength
)
876 bool IODTPlatformExpert::getMachineName( char * name
, int maxLength
)
882 prop
= (OSData
*) getProvider()->getProperty( gIODTModelKey
);
886 strncpy( name
, (const char *) prop
->getBytesNoCopy(), maxLength
);
891 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
893 void IODTPlatformExpert::registerNVRAMController( IONVRAMController
* nvram
)
895 if (dtNVRAM
) dtNVRAM
->registerNVRAMController(nvram
);
897 super::registerNVRAMController(nvram
);
900 int IODTPlatformExpert::haltRestart(unsigned int type
)
902 if (dtNVRAM
) dtNVRAM
->sync();
904 return super::haltRestart(type
);
907 IOReturn
IODTPlatformExpert::readXPRAM(IOByteCount offset
, UInt8
* buffer
,
910 if (dtNVRAM
) return dtNVRAM
->readXPRAM(offset
, buffer
, length
);
911 else return kIOReturnNotReady
;
914 IOReturn
IODTPlatformExpert::writeXPRAM(IOByteCount offset
, UInt8
* buffer
,
917 if (dtNVRAM
) return dtNVRAM
->writeXPRAM(offset
, buffer
, length
);
918 else return kIOReturnNotReady
;
921 IOReturn
IODTPlatformExpert::readNVRAMProperty(
922 IORegistryEntry
* entry
,
923 const OSSymbol
** name
, OSData
** value
)
925 if (dtNVRAM
) return dtNVRAM
->readNVRAMProperty(entry
, name
, value
);
926 else return kIOReturnNotReady
;
929 IOReturn
IODTPlatformExpert::writeNVRAMProperty(
930 IORegistryEntry
* entry
,
931 const OSSymbol
* name
, OSData
* value
)
933 if (dtNVRAM
) return dtNVRAM
->writeNVRAMProperty(entry
, name
, value
);
934 else return kIOReturnNotReady
;
937 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
940 #define super IOService
942 OSDefineMetaClassAndStructors(IOPlatformExpertDevice
, IOService
)
944 OSMetaClassDefineReservedUnused(IOPlatformExpertDevice
, 0);
945 OSMetaClassDefineReservedUnused(IOPlatformExpertDevice
, 1);
946 OSMetaClassDefineReservedUnused(IOPlatformExpertDevice
, 2);
947 OSMetaClassDefineReservedUnused(IOPlatformExpertDevice
, 3);
949 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
951 bool IOPlatformExpertDevice::compareName( OSString
* name
,
952 OSString
** matched
= 0 ) const
954 return( IODTCompareNubName( this, name
, matched
));
958 IOPlatformExpertDevice::initWithArgs(
959 void * dtTop
, void * p2
, void * p3
, void * p4
)
961 IORegistryEntry
* dt
= 0;
962 void * argsData
[ 4 ];
965 // dtTop may be zero on non- device tree systems
966 if( dtTop
&& (dt
= IODeviceTreeAlloc( dtTop
)))
967 ok
= super::init( dt
, gIODTPlane
);
974 workLoop
= IOWorkLoop::workLoop();
978 argsData
[ 0 ] = dtTop
;
983 setProperty("IOPlatformArgs", (void *)argsData
, sizeof( argsData
));
988 IOWorkLoop
*IOPlatformExpertDevice::getWorkLoop() const
993 void IOPlatformExpertDevice::free()
999 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1002 #define super IOService
1004 OSDefineMetaClassAndStructors(IOPlatformDevice
, IOService
)
1006 OSMetaClassDefineReservedUnused(IOPlatformDevice
, 0);
1007 OSMetaClassDefineReservedUnused(IOPlatformDevice
, 1);
1008 OSMetaClassDefineReservedUnused(IOPlatformDevice
, 2);
1009 OSMetaClassDefineReservedUnused(IOPlatformDevice
, 3);
1011 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1013 bool IOPlatformDevice::compareName( OSString
* name
,
1014 OSString
** matched
= 0 ) const
1016 return( ((IOPlatformExpert
*)getProvider())->
1017 compareNubName( this, name
, matched
));
1020 IOService
* IOPlatformDevice::matchLocation( IOService
* /* client */ )
1025 IOReturn
IOPlatformDevice::getResources( void )
1027 return( ((IOPlatformExpert
*)getProvider())->getNubResources( this ));
1030 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1032 /*********************************************************************
1033 * IOPanicPlatform class
1035 * If no legitimate IOPlatformDevice matches, this one does and panics
1036 * the kernel with a suitable message.
1037 *********************************************************************/
1039 class IOPanicPlatform
: IOPlatformExpert
{
1040 OSDeclareDefaultStructors(IOPanicPlatform
);
1043 bool start(IOService
* provider
);
1047 OSDefineMetaClassAndStructors(IOPanicPlatform
, IOPlatformExpert
);
1050 bool IOPanicPlatform::start(IOService
* provider
) {
1051 const char * platform_name
= "(unknown platform name)";
1053 if (provider
) platform_name
= provider
->getName();
1055 panic("Unable to find driver for this platform: \"%s\".\n",