|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
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.
11: *
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
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * HISTORY
24: */
25:
26: #include <IOKit/system.h>
27:
28: extern "C" {
29: #include <machine/machine_routines.h>
30: }
31:
32: #include <IOKit/IOInterrupts.h>
33: #include <IOKit/IOInterruptController.h>
34: #include <IOKit/IOPlatformExpert.h>
35: #include <IOKit/IOCPU.h>
36: #include <IOKit/IODeviceTreeSupport.h>
37: #include <IOKit/IORangeAllocator.h>
38: #include <libkern/c++/OSContainers.h>
39: #include <IOKit/IOLib.h>
40: #include <IOKit/nvram/IONVRAMController.h>
41: #include <IOKit/pwr_mgt/RootDomain.h>
42: #include <IOKit/IOKitDebug.h>
43: #include <IOKit/IOWorkLoop.h>
44:
45: #include <IOKit/assert.h>
46:
47: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48:
49: #define super IOService
50:
51: OSDefineMetaClassAndStructors(IOPlatformExpert, IOService)
52:
53: static IOPlatformExpert * gIOPlatform;
54:
55: OSSymbol * gPlatformInterruptControllerName;
56:
57: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
58:
59: bool IOPlatformExpert::attach( IOService * provider )
60: {
61:
62: if( !super::attach( provider ))
63: return( false);
64:
65: return( true);
66: }
67:
68: bool IOPlatformExpert::start( IOService * provider )
69: {
70: IORangeAllocator * physicalRanges;
71:
72: if (!super::start(provider))
73: return false;
74:
75: gPlatformInterruptControllerName = (OSSymbol *)OSSymbol::withCStringNoCopy("IOPlatformInterruptController");
76:
77: physicalRanges = IORangeAllocator::withRange(0xffffffff, 1, 16,
78: IORangeAllocator::kLocking);
79: assert(physicalRanges);
80: setProperty("Platform Memory Ranges", physicalRanges);
81:
82: setPlatform( this );
83: gIOPlatform = this;
84:
85: PMInstantiatePowerDomains();
86:
87: return( configure(provider) );
88: }
89:
90: bool IOPlatformExpert::configure( IOService * provider )
91: {
92: OSSet * topLevel;
93: OSDictionary * dict;
94: IOService * nub;
95:
96: topLevel = OSDynamicCast( OSSet, getProperty("top-level"));
97:
98: if( topLevel) {
99: while( (dict = OSDynamicCast( OSDictionary,
100: topLevel->getAnyObject()))) {
101: dict->retain();
102: topLevel->removeObject( dict );
103: nub = createNub( dict );
104: if( 0 == nub)
105: continue;
106: dict->release();
107: nub->attach( this );
108: nub->registerService();
109: }
110: }
111:
112: return( true );
113: }
114:
115: IOService * IOPlatformExpert::createNub( OSDictionary * from )
116: {
117: IOService * nub;
118:
119: nub = new IOPlatformDevice;
120: if(nub) {
121: if( !nub->init( from )) {
122: nub->release();
123: nub = 0;
124: }
125: }
126: return( nub);
127: }
128:
129: bool IOPlatformExpert::compareNubName( const IOService * nub,
130: OSString * name, OSString ** matched = 0 ) const
131: {
132: return( nub->IORegistryEntry::compareName( name, matched ));
133: }
134:
135: IOReturn IOPlatformExpert::getNubResources( IOService * nub )
136: {
137: return( kIOReturnSuccess );
138: }
139:
140: int IOPlatformExpert::getEpoch(void)
141: {
142: return _peEpoch;
143: }
144:
145: int IOPlatformExpert::getFamily(void)
146: {
147: return _peFamily;
148: }
149:
150: void IOPlatformExpert::setEpoch(int peEpoch)
151: {
152: _peEpoch = peEpoch;
153: }
154:
155: void IOPlatformExpert::setFamily(int peFamily)
156: {
157: _peFamily = peFamily;
158: }
159:
160: bool IOPlatformExpert::getMachineName( char * /*name*/, int /*maxLength*/)
161: {
162: return( false );
163: }
164:
165: bool IOPlatformExpert::getModelName( char * /*name*/, int /*maxLength*/)
166: {
167: return( false );
168: }
169:
170: IORangeAllocator * IOPlatformExpert::getPhysicalRangeAllocator(void)
171: {
172: return(OSDynamicCast(IORangeAllocator,
173: getProperty("Platform Memory Ranges")));
174: }
175:
176: int (*PE_halt_restart)(unsigned int type) = 0;
177:
178: int IOPlatformExpert::haltRestart(unsigned int type)
179: {
180:
181: if (PE_halt_restart) return (*PE_halt_restart)(type);
182: else return -1;
183: }
184:
185: long IOPlatformExpert::getGMTTimeOfDay(void)
186: {
187: return(0);
188: }
189:
190: void IOPlatformExpert::setGMTTimeOfDay(long secs)
191: {
192: }
193:
194:
195: IOReturn IOPlatformExpert::getConsoleInfo( PE_Video * consoleInfo )
196: {
197: return( PE_current_console( consoleInfo));
198: }
199:
200: IOReturn IOPlatformExpert::setConsoleInfo( PE_Video * consoleInfo,
201: unsigned int op)
202: {
203: return( PE_initialize_console( consoleInfo, op ));
204: }
205:
206: void IOPlatformExpert::getDefaultBusSpeeds(int *numSpeeds,
207: unsigned long **speedList)
208: {
209: if (numSpeeds != 0) *numSpeeds = 0;
210: if (speedList != 0) *speedList = 0;
211: }
212:
213: IOReturn IOPlatformExpert::registerInterruptController(OSSymbol *name, IOInterruptController *interruptController)
214: {
215: publishResource(name, interruptController);
216:
217: return kIOReturnSuccess;
218: }
219:
220: IOInterruptController *IOPlatformExpert::lookUpInterruptController(OSSymbol *name)
221: {
222: IOInterruptController *interruptController;
223: IOService *service;
224:
225: service = waitForService(resourceMatching(name));
226:
227: interruptController = OSDynamicCast(IOInterruptController, service->getProperty(name));
228:
229: return interruptController;
230: }
231:
232:
233: void IOPlatformExpert::setCPUInterruptProperties(IOService *service)
234: {
235: IOCPUInterruptController *controller;
236:
237: controller = OSDynamicCast(IOCPUInterruptController, waitForService(serviceMatching("IOCPUInterruptController")));
238: if (controller) controller->setCPUInterruptProperties(service);
239: }
240:
241: bool IOPlatformExpert::atInterruptLevel(void)
242: {
243: return ml_at_interrupt_context();
244: }
245:
246: bool IOPlatformExpert::platformAdjustService(IOService */*service*/)
247: {
248: return true;
249: }
250:
251:
252: //*********************************************************************************
253: // PMLog
254: //
255: //*********************************************************************************
256:
257: void IOPlatformExpert::PMLog(const char * who,unsigned long event,unsigned long param1, unsigned long param2)
258: {
259: if( gIOKitDebug & kIOLogPower)
260: kprintf("%s %02d %08x %08x\n",who,event,param1,param2);
261: }
262:
263:
264: //*********************************************************************************
265: // PMInstantiatePowerDomains
266: //
267: // In this vanilla implementation, a Root Power Domain is instantiated.
268: // All other objects which register will be children of this Root.
269: // Where this is inappropriate, PMInstantiatePowerDomains is overridden
270: // in a platform-specific subclass.
271: //*********************************************************************************
272:
273: void IOPlatformExpert::PMInstantiatePowerDomains ( void )
274: {
275: root = new IOPMrootDomain;
276: root->init();
277: root->attach(this);
278: root->start(this);
279: root->youAreRoot();
280: }
281:
282:
283: //*********************************************************************************
284: // PMRegisterDevice
285: //
286: // In this vanilla implementation, all callers are made children of the root power domain.
287: // Where this is inappropriate, PMRegisterDevice is overridden in a platform-specific subclass.
288: //*********************************************************************************
289:
290: void IOPlatformExpert::PMRegisterDevice(IOService * theNub, IOService * theDevice)
291: {
292: root->addChild ( theDevice );
293: }
294:
295:
296: /*
297: * Platform Expert handler for Non-volatile RAM.
298: Called by BSD driver.
299: Calls whatever NVRAM driver has registered.
300: That's either the IOPMUNVRAMController or the IOMapNVRAMController.
301:
302: Suurballe 11 Feb 1999
303: */
304:
305:
306: // global pointer to whichever NVRAM controller is present
307: IONVRAMController * gNVRAMController = 0;
308:
309: extern "C" {
310:
311: //int PEnvopen(dev_t dev, int flag, int devtype,struct proc * pp)
312: int PEnvopen(dev_t, int, int,struct proc * )
313: {
314: if (gNVRAMController) return gNVRAMController->openNVRAM();
315: else return kNoNVRAM;
316: }
317:
318:
319: //int PEnvclose(dev_t dev, int flag, int mode, struct proc * pp)
320: int PEnvclose(dev_t, int, int, struct proc *)
321: {
322: if (gNVRAMController) return gNVRAMController->closeNVRAM();
323: else return kNoNVRAM;
324: }
325:
326:
327: int PEnvsync(void)
328: {
329: if (gNVRAMController) return gNVRAMController->syncNVRAM();
330: else return kNoNVRAM;
331: }
332:
333:
334: int PEnvread(long offset, int length, unsigned char * where)
335: {
336: IOByteCount bytecount = length;
337:
338: if (gNVRAMController)
339: return gNVRAMController->readNVRAM(offset, &bytecount, where);
340: else return kNoNVRAM;
341: }
342:
343:
344:
345: int PEnvwrite(long offset, int length, unsigned char * where)
346: {
347: IOByteCount bytecount = length;
348:
349: if (gNVRAMController)
350: return gNVRAMController->writeNVRAM(offset, &bytecount, where);
351: else return kNoNVRAM;
352: }
353:
354: /*
355: * Callouts from BSD for machine name & model
356: */
357:
358: boolean_t PEGetMachineName( char * name, int maxLength )
359: {
360: if( gIOPlatform)
361: return( gIOPlatform->getMachineName( name, maxLength ));
362: else
363: return( false );
364: }
365:
366: boolean_t PEGetModelName( char * name, int maxLength )
367: {
368: if( gIOPlatform)
369: return( gIOPlatform->getModelName( name, maxLength ));
370: else
371: return( false );
372: }
373:
374: int PEGetPlatformEpoch(void)
375: {
376: if( gIOPlatform)
377: return( gIOPlatform->getEpoch());
378: else
379: return( -1 );
380: }
381:
382: int PEHaltRestart(unsigned int type)
383: {
384: if (gNVRAMController) gNVRAMController->syncNVRAM();
385:
386: if (gIOPlatform) return gIOPlatform->haltRestart(type);
387: else return -1;
388: }
389:
390: long PEGetGMTTimeOfDay(void)
391: {
392: if( gIOPlatform)
393: return( gIOPlatform->getGMTTimeOfDay());
394: else
395: return( 0 );
396: }
397:
398: void PESetGMTTimeOfDay(long secs)
399: {
400: if( gIOPlatform)
401: gIOPlatform->setGMTTimeOfDay(secs);
402: }
403:
404: } /* extern "C" */
405:
406: void IOPlatformExpert::registerNVRAMController(IONVRAMController * caller)
407: {
408: gNVRAMController = caller;
409:
410: publishResource("IONVRAM");
411: }
412:
413:
414: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
415:
416: #undef super
417: #define super IOPlatformExpert
418:
419: OSDefineMetaClass(IODTPlatformExpert, IOPlatformExpert)
420: OSDefineAbstractStructors( IODTPlatformExpert, IOPlatformExpert )
421:
422: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
423:
424: IOService * IODTPlatformExpert::probe( IOService * provider,
425: SInt32 * score )
426: {
427: if( !super::probe( provider, score))
428: return( 0 );
429:
430: // check machine types
431: if( !provider->compareNames( getProperty( gIONameMatchKey ) ))
432: return( 0 );
433:
434: return( this);
435: }
436:
437: bool IODTPlatformExpert::configure( IOService * provider )
438: {
439: if( !super::configure( provider))
440: return( false);
441:
442: processTopLevel( provider );
443:
444: return( true );
445: }
446:
447: IOService * IODTPlatformExpert::createNub( IORegistryEntry * from )
448: {
449: IOService * nub;
450:
451: nub = new IOPlatformDevice;
452: if( nub) {
453: if( !nub->init( from, gIODTPlane )) {
454: nub->free();
455: nub = 0;
456: }
457: }
458: return( nub);
459: }
460:
461: bool IODTPlatformExpert::createNubs( IOService * parent, OSIterator * iter )
462: {
463: IORegistryEntry * next;
464: IOService * nub;
465: bool ok = true;
466:
467: if( iter) {
468: while( (next = (IORegistryEntry *) iter->getNextObject())) {
469:
470: if( 0 == (nub = createNub( next )))
471: continue;
472:
473: nub->attach( parent );
474: nub->registerService();
475: }
476: iter->release();
477: }
478:
479: return( ok );
480: }
481:
482: void IODTPlatformExpert::processTopLevel( IORegistryEntry * root )
483: {
484: OSIterator * kids;
485: IORegistryEntry * next;
486: IORegistryEntry * cpus;
487:
488: // infanticide
489: kids = IODTFindMatchingEntries( root, 0, deleteList() );
490: if( kids) {
491: while( (next = (IORegistryEntry *)kids->getNextObject())) {
492: next->detachAll( gIODTPlane);
493: }
494: kids->release();
495: }
496:
497: // publish top level, minus excludeList
498: createNubs( this, IODTFindMatchingEntries( root, kIODTExclusive, excludeList()));
499:
500: cpus = root->childFromPath( "cpus", gIODTPlane);
501: // kids = IODTFindMatchingEntries( root, 0, "cpus");
502: // cpus = (IORegistryEntry *)kids->getNextObject();
503: if ( cpus)
504: // publish cpus/*
505: createNubs( this, IODTFindMatchingEntries( cpus, kIODTExclusive, 0));
506:
507: }
508:
509: IOReturn IODTPlatformExpert::getNubResources( IOService * nub )
510: {
511: if( nub->getDeviceMemory())
512: return( kIOReturnSuccess );
513:
514: IODTResolveAddressing( nub, "reg", 0);
515:
516: return( kIOReturnSuccess);
517: }
518:
519: bool IODTPlatformExpert::compareNubName( const IOService * nub,
520: OSString * name, OSString ** matched ) const
521: {
522: return( IODTCompareNubName( nub, name, matched )
523: || super::compareNubName( nub, name, matched) );
524: }
525:
526: bool IODTPlatformExpert::getModelName( char * name, int maxLength )
527: {
528: OSData * prop;
529: const char * str;
530: int len;
531: char c;
532: bool ok = false;
533:
534: maxLength--;
535:
536: prop = (OSData *) getProvider()->getProperty( gIODTCompatibleKey );
537: if( prop ) {
538: str = (const char *) prop->getBytesNoCopy();
539:
540: if( 0 == strncmp( str, "AAPL,", strlen( "AAPL," ) ))
541: str += strlen( "AAPL," );
542:
543: len = 0;
544: while( (c = *str++)) {
545: if( (c == '/') || (c == ' '))
546: c = '-';
547:
548: name[ len++ ] = c;
549: if( len >= maxLength)
550: break;
551: }
552:
553: name[ len ] = 0;
554: ok = true;
555: }
556: return( ok );
557: }
558:
559: bool IODTPlatformExpert::getMachineName( char * name, int maxLength )
560: {
561: OSData * prop;
562: bool ok = false;
563:
564: maxLength--;
565: prop = (OSData *) getProvider()->getProperty( gIODTModelKey );
566: ok = (0 != prop);
567:
568: if( ok )
569: strncpy( name, (const char *) prop->getBytesNoCopy(), maxLength );
570:
571: return( ok );
572: }
573:
574: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
575:
576: enum {
577: kMaxNVNameLen = 4,
578: kMaxNVDataLen = 8
579: };
580:
581: #pragma options align=mac68k
582: struct NVRAMProperty
583: {
584: IONVRAMDescriptor header;
585: UInt8 nameLen;
586: UInt8 name[ kMaxNVNameLen ];
587: UInt8 dataLen;
588: UInt8 data[ kMaxNVDataLen ];
589: };
590: #pragma options align=reset
591:
592:
593: void IODTPlatformExpert::registerNVRAMController( IONVRAMController * nvram )
594: {
595: UInt32 off;
596: IOReturn err;
597: IOByteCount len;
598:
599: err = getNVRAMPartitionOffset( kIONameRegistryNVRAMPartition, &off );
600:
601: if( kIOReturnSuccess == err) {
602:
603: if( 0 == nvramBuffer)
604: nvramBuffer = IONew( UInt8, kIONameRegistryNVRAMPartitionSize );
605: assert( nvramBuffer );
606:
607: err = nvram->openNVRAM();
608: if( kIOReturnSuccess == err) {
609: len = kIONameRegistryNVRAMPartitionSize;
610: err = nvram->readNVRAM( off, &len, nvramBuffer );
611: nvram->closeNVRAM();
612: }
613:
614: if( err)
615: bzero( nvramBuffer, kIONameRegistryNVRAMPartitionSize );
616: }
617:
618: super::registerNVRAMController( nvram );
619: }
620:
621: bool IODTPlatformExpert::searchNVRAMProperty( IONVRAMDescriptor * hdr,
622: UInt32 * where )
623: {
624: UInt32 off;
625: SInt32 nvEnd;
626:
627: getNVRAMPartitionOffset( kIONameRegistryNVRAMPartition, &off );
628:
629: nvEnd = *((UInt16 *) nvramBuffer);
630: if( getEpoch())
631: nvEnd -= 0x100; // on new world, offset to partition start
632: else
633: nvEnd -= off; // on old world, absolute
634: if( (nvEnd < 0) || (nvEnd >= kIONameRegistryNVRAMPartitionSize) )
635: nvEnd = 2;
636:
637: off = 2;
638: while( (off + sizeof( NVRAMProperty)) <= (UInt32) nvEnd) {
639:
640: if( 0 == bcmp( nvramBuffer + off, hdr, sizeof( *hdr))) {
641: *where = off;
642: return( true );
643: }
644: off += sizeof( NVRAMProperty);
645: }
646:
647: if( (nvEnd + sizeof( NVRAMProperty)) <= kIONameRegistryNVRAMPartitionSize)
648: *where = nvEnd;
649: else
650: *where = 0;
651:
652: return( false );
653: }
654:
655: IOReturn IODTPlatformExpert::readNVRAMPropertyType0(
656: IORegistryEntry * entry,
657: const OSSymbol ** name, OSData ** value )
658: {
659: IONVRAMDescriptor hdr;
660: NVRAMProperty * prop;
661: IOByteCount len;
662: UInt32 off;
663: IOReturn err;
664: char nameBuf[ kMaxNVNameLen + 1 ];
665:
666: if( !nvramBuffer)
667: return( kIOReturnUnsupported );
668: if( !entry || !name || !value)
669: return( kIOReturnBadArgument );
670:
671: if( kIOReturnSuccess != (err = IODTMakeNVDescriptor( entry, &hdr)))
672: return( err);
673:
674: if( searchNVRAMProperty( &hdr, &off)) {
675:
676: prop = (NVRAMProperty *) (nvramBuffer + off);
677:
678: len = prop->nameLen;
679: if( len > kMaxNVNameLen)
680: len = kMaxNVNameLen;
681: strncpy( nameBuf, (const char *) prop->name, len );
682: nameBuf[ len ] = 0;
683: *name = OSSymbol::withCString( nameBuf );
684:
685: len = prop->dataLen;
686: if( len > kMaxNVDataLen)
687: len = kMaxNVDataLen;
688: *value = OSData::withBytes( prop->data, len );
689:
690: if( *name && *value )
691: return( kIOReturnSuccess );
692: else
693: return( kIOReturnNoMemory );
694: }
695:
696: return( kIOReturnNoResources );
697: }
698:
699: IOReturn IODTPlatformExpert::writeNVRAMPropertyType0(
700: IORegistryEntry * entry,
701: const OSSymbol * name, OSData * value )
702: {
703: IONVRAMDescriptor hdr;
704: NVRAMProperty * prop;
705: IOByteCount len;
706: IOByteCount nameLen;
707: IOByteCount dataLen;
708: UInt32 off;
709: IOReturn err;
710: UInt32 start;
711: UInt16 nvLen;
712: bool exists;
713:
714: if( !nvramBuffer)
715: return( kIOReturnUnsupported );
716: if( !entry || !name || !value)
717: return( kIOReturnBadArgument );
718:
719: nameLen = name->getLength();
720: dataLen = value->getLength();
721: if( nameLen > kMaxNVNameLen)
722: return( kIOReturnNoSpace);
723: if( dataLen > kMaxNVDataLen)
724: return( kIOReturnNoSpace);
725:
726: if( kIOReturnSuccess != (err = IODTMakeNVDescriptor( entry, &hdr)))
727: return( err);
728:
729: exists = searchNVRAMProperty( &hdr, &off);
730: if( !off)
731: return( kIOReturnNoMemory);
732:
733: prop = (NVRAMProperty *) (nvramBuffer + off);
734: if( !exists)
735: bcopy( &hdr, &prop->header, sizeof( hdr));
736:
737: prop->nameLen = nameLen;
738: bcopy( name->getCStringNoCopy(), prop->name, nameLen );
739: prop->dataLen = dataLen;
740: bcopy( value->getBytesNoCopy(), prop->data, dataLen );
741:
742: getNVRAMPartitionOffset( kIONameRegistryNVRAMPartition, &start );
743: if( !exists) {
744: nvLen = off + sizeof( NVRAMProperty);
745: if( getEpoch())
746: nvLen += 0x100;
747: else
748: nvLen += start;
749: *((UInt16 *) nvramBuffer) = nvLen;
750: }
751:
752: err = gNVRAMController->openNVRAM();
753: if( kIOReturnSuccess == err) {
754: len = 2;
755: if( !exists)
756: err = gNVRAMController->writeNVRAM( start, &len, nvramBuffer );
757: if( kIOReturnSuccess == err) {
758: len = sizeof( NVRAMProperty);
759: err = gNVRAMController->writeNVRAM( start + off, &len,
760: nvramBuffer + off );
761: }
762: gNVRAMController->closeNVRAM();
763: }
764:
765: return( err );
766: }
767:
768: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
769:
770: OSData * IODTPlatformExpert::getType1NVRAM( void )
771: {
772: OSData * data;
773: IORegistryEntry * options;
774:
775: options = IORegistryEntry::fromPath( "/options", gIODTPlane);
776: if( !options)
777: return( 0 );
778:
779: data = OSDynamicCast( OSData, options->getProperty( "aapl,pci" ));
780: if( data && (0 == data->getLength()))
781: data = 0;
782:
783: return( data );
784: }
785:
786: OSData * IODTPlatformExpert::unescapeValueToBinary( UInt8 * value )
787: {
788: OSData * data = 0;
789: UInt8 * buffer;
790: UInt32 len, totalLen = 0;
791: UInt8 byte;
792: enum { kMaxValueSize = 256 };
793:
794: buffer = IONew( UInt8, kMaxValueSize );
795: if( !buffer)
796: return( 0 );
797:
798: while( 0 != (byte = *(value++))) {
799:
800: if( 0xff == byte) {
801: byte = *(value++);
802: len = byte & 0x7f;
803: byte = (byte & 0x80) ? 0xff : 0;
804: } else
805: len = 1;
806:
807: if( (totalLen + len) >= kMaxValueSize) {
808: totalLen = 0;
809: break;
810: }
811:
812: memset( (void *) (buffer + totalLen), byte, len );
813: totalLen += len;
814: }
815:
816: if( totalLen)
817: data = OSData::withBytes( buffer, totalLen );
818:
819: IODelete( buffer, UInt8, kMaxValueSize );
820:
821: return( data );
822: }
823:
824: IOReturn IODTPlatformExpert::readNVRAMPropertyType1(
825: IORegistryEntry * entry,
826: const OSSymbol ** name, OSData ** value )
827: {
828: IOReturn err = kIOReturnNoResources;
829: OSData * data;
830: UInt8 * start;
831: UInt8 * end;
832: UInt8 * where;
833: UInt8 * nvPath = 0;
834: UInt8 * nvName = 0;
835: UInt8 byte;
836:
837: if( 0 == (data = getType1NVRAM()))
838: return( kIOReturnUnsupported );
839:
840: // data must have length from getType1NVRAM()
841: start = (UInt8 *) data->getBytesNoCopy();
842: if( strlen( (const char *) start) == (data->getLength() - 1)) {
843: data = unescapeValueToBinary( start );
844: if( 0 == data)
845: return( kIOReturnUnsupported );
846: } else
847: data->retain();
848:
849: start = (UInt8 *) data->getBytesNoCopy();
850: end = start + data->getLength();
851:
852: where = start;
853: while( where < end) {
854:
855: byte = *(where++);
856: if( byte)
857: continue;
858:
859: if( !nvPath)
860: nvPath = start;
861: else if( !nvName)
862: nvName = start;
863:
864: else if( entry == IORegistryEntry::fromPath( (const char *) nvPath, gIODTPlane )) {
865:
866: *name = OSSymbol::withCString( (const char *) nvName );
867: *value = unescapeValueToBinary( start );
868: if( *name && *value )
869: err = kIOReturnSuccess;
870: else
871: err = kIOReturnNoMemory;
872: break;
873:
874: } else
875: nvPath = nvName = 0;
876:
877: start = where;
878: }
879: data->release();
880:
881: return( err );
882: }
883:
884: IOReturn IODTPlatformExpert::writeNVRAMPropertyType1(
885: IORegistryEntry * entry,
886: const OSSymbol * name, OSData * value )
887: {
888: OSData * data;
889:
890: if( 0 == (data = getType1NVRAM()))
891: return( kIOReturnUnsupported );
892:
893: // tidbit left for PR2
894: return( kIOReturnNoResources );
895: }
896:
897: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
898:
899:
900: IOReturn IODTPlatformExpert::readNVRAMProperty(
901: IORegistryEntry * entry,
902: const OSSymbol ** name, OSData ** value )
903: {
904: IOReturn err;
905:
906: err = readNVRAMPropertyType1( entry, name, value );
907:
908: if( kIOReturnUnsupported == err)
909: err = readNVRAMPropertyType0( entry, name, value );
910:
911: return( err );
912: }
913:
914: IOReturn IODTPlatformExpert::writeNVRAMProperty(
915: IORegistryEntry * entry,
916: const OSSymbol * name, OSData * value )
917: {
918: IOReturn err;
919:
920: err = writeNVRAMPropertyType1( entry, name, value );
921:
922: if( kIOReturnUnsupported == err)
923: err = writeNVRAMPropertyType0( entry, name, value );
924:
925: return( err );
926: }
927:
928: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
929:
930: #undef super
931: #define super IOService
932:
933: OSDefineMetaClassAndStructors(IOPlatformExpertDevice, IOService)
934:
935: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
936:
937: bool IOPlatformExpertDevice::compareName( OSString * name,
938: OSString ** matched = 0 ) const
939: {
940: return( IODTCompareNubName( this, name, matched ));
941: }
942:
943: bool
944: IOPlatformExpertDevice::initWithArgs(
945: void * dtTop, void * p2, void * p3, void * p4 )
946: {
947: IORegistryEntry * dt = 0;
948: void * argsData[ 4 ];
949: bool ok;
950:
951: // dtTop may be zero on non- device tree systems
952: if( dtTop && (dt = IODeviceTreeAlloc( dtTop )))
953: ok = super::init( dt, gIODTPlane );
954: else
955: ok = super::init();
956:
957: if( !ok)
958: return( false);
959:
960: workLoop = IOWorkLoop::workLoop();
961: if (!workLoop)
962: return false;
963:
964: argsData[ 0 ] = dtTop;
965: argsData[ 1 ] = p2;
966: argsData[ 2 ] = p3;
967: argsData[ 3 ] = p4;
968:
969: setProperty("IOPlatformArgs", (void *)argsData, sizeof( argsData));
970:
971: return( true);
972: }
973:
974: IOWorkLoop *IOPlatformExpertDevice::getWorkLoop() const
975: {
976: return workLoop;
977: }
978:
979: void IOPlatformExpertDevice::free()
980: {
981: if (workLoop)
982: workLoop->release();
983: }
984:
985: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
986:
987: #undef super
988: #define super IOService
989:
990: OSDefineMetaClassAndStructors(IOPlatformDevice, IOService)
991:
992: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
993:
994: bool IOPlatformDevice::compareName( OSString * name,
995: OSString ** matched = 0 ) const
996: {
997: return( ((IOPlatformExpert *)getProvider())->
998: compareNubName( this, name, matched ));
999: }
1000:
1001: IOService * IOPlatformDevice::matchLocation( IOService * /* client */ )
1002: {
1003: return( this );
1004: }
1005:
1006: IOReturn IOPlatformDevice::getResources( void )
1007: {
1008: return( ((IOPlatformExpert *)getProvider())->getNubResources( this ));
1009: }
1010:
1011: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.