Annotation of XNU/iokit/Kernel/IOPlatformExpert.cpp, revision 1.1

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: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.