Annotation of XNU/iokit/Families/IONDRVSupport/IONDRVLibraries.cpp, revision 1.1.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:  * Copyright (c) 1997 Apple Computer, Inc.
                     24:  *
                     25:  *
                     26:  * HISTORY
                     27:  *
                     28:  * sdouglas  22 Oct 97 - first checked in.
                     29:  * sdouglas  21 Jul 98 - start IOKit
                     30:  * sdouglas  14 Dec 98 - start cpp.
                     31:  */
                     32: 
                     33: 
                     34: #include <IOKit/IOLib.h>
                     35: #include <libkern/c++/OSContainers.h>
                     36: #include <IOKit/IODeviceTreeSupport.h>
                     37: #include <IOKit/IOPlatformExpert.h>
                     38: #include <IOKit/pci/IOPCIDevice.h>
                     39: #include <IOKit/ndrvsupport/IONDRVFramebuffer.h>
                     40: 
                     41: #include <libkern/OSByteOrder.h>
                     42: #include <libkern/OSAtomic.h>
                     43: #include <IOKit/assert.h>
                     44: 
                     45: #include <pexpert/pexpert.h>
                     46: 
                     47: #include "IOPEFLibraries.h"
                     48: #include "IOPEFLoader.h"
                     49: #include "IONDRV.h"
                     50: 
                     51: #include <string.h>
                     52: 
                     53: extern "C"
                     54: {
                     55: 
                     56: extern void *kern_os_malloc(size_t size);
                     57: extern void kern_os_free(void * addr);
                     58: 
                     59: #define LOG            if(1) kprintf
                     60: 
                     61: #define LOGNAMEREG     0
                     62: 
                     63: /* NameRegistry error codes */
                     64: enum {
                     65:     nrLockedErr                    = -2536,
                     66:     nrNotEnoughMemoryErr        = -2537,
                     67:     nrInvalidNodeErr            = -2538,
                     68:     nrNotFoundErr                = -2539,
                     69:     nrNotCreatedErr                = -2540,
                     70:     nrNameErr                     = -2541,
                     71:     nrNotSlotDeviceErr            = -2542,
                     72:     nrDataTruncatedErr            = -2543,
                     73:     nrPowerErr                    = -2544,
                     74:     nrPowerSwitchAbortErr        = -2545,
                     75:     nrTypeMismatchErr            = -2546,
                     76:     nrNotModifiedErr            = -2547,
                     77:     nrOverrunErr                = -2548,
                     78:     nrResultCodeBase             = -2549,
                     79:     nrPathNotFound                 = -2550,    /* a path component lookup failed */
                     80:     nrPathBufferTooSmall         = -2551,    /* buffer for path is too small */    
                     81:     nrInvalidEntryIterationOp     = -2552,    /* invalid entry iteration operation */
                     82:     nrPropertyAlreadyExists     = -2553,    /* property already exists */
                     83:     nrIterationDone                = -2554,    /* iteration operation is done */
                     84:     nrExitedIteratorScope        = -2555,    /* outer scope of iterator was exited */
                     85:     nrTransactionAborted        = -2556        /* transaction was aborted */
                     86: };
                     87: 
                     88: enum {
                     89:     kNVRAMProperty             = 0x00000020L,            // matches NR
                     90:     kRegMaximumPropertyNameLength      = 31
                     91: };
                     92: 
                     93: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                     94: 
                     95: UInt32 _eEndianSwap32Bit( UInt32 data )
                     96: {
                     97:     return( OSReadSwapInt32(&data, 0));
                     98: }
                     99: 
                    100: UInt16 _eEndianSwap16Bit( UInt16 data )
                    101: {
                    102:     return( OSReadSwapInt16(&data, 0));
                    103: }
                    104: 
                    105: OSStatus _eExpMgrConfigReadLong( RegEntryID entryID, UInt8 offset, UInt32 * value )
                    106: {
                    107: 
                    108:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    109: 
                    110:     *value = ioDevice->configRead32( offset );
                    111: 
                    112:     return( noErr );
                    113: }
                    114: 
                    115: OSStatus _eExpMgrConfigWriteLong( RegEntryID entryID, UInt8 offset, UInt32 value )
                    116: {
                    117: 
                    118:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    119: 
                    120:     ioDevice->configWrite32( offset, value);
                    121: 
                    122:     return( noErr );
                    123: }
                    124: 
                    125: 
                    126: OSStatus _eExpMgrConfigReadWord( RegEntryID entryID, UInt8 offset, UInt16 * value )
                    127: {
                    128:     OSStatus   err;
                    129:     UInt32     lvalue;
                    130: 
                    131:     err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
                    132:     if( offset & 2)
                    133:        *value = lvalue >> 16;
                    134:     else
                    135:        *value = lvalue;
                    136:     return( err);
                    137: }
                    138: 
                    139: OSStatus _eExpMgrConfigWriteWord( RegEntryID entryID, UInt8 offset, UInt16 value )
                    140: {
                    141:     OSStatus   err;
                    142:     UInt32     lvalue;
                    143: 
                    144:     err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
                    145: 
                    146:     if( offset & 2)
                    147:        lvalue = (lvalue & 0xffff) | (value << 16);
                    148:     else
                    149:        lvalue = (lvalue & 0xffff0000) | value;
                    150: 
                    151:     err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
                    152:     return( err);
                    153: }
                    154: 
                    155: OSStatus _eExpMgrConfigReadByte( RegEntryID entryID, UInt8 offset, UInt8 * value )
                    156: {
                    157:     OSStatus   err;
                    158:     UInt32     lvalue;
                    159: 
                    160:     err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
                    161:     *value = lvalue >> ((offset & 3) * 8);
                    162:     return( err);
                    163: }
                    164: 
                    165: OSStatus _eExpMgrConfigWriteByte( RegEntryID entryID, UInt8 offset, UInt8 value )
                    166: {
                    167:     OSStatus   err;
                    168:     UInt32     lvalue;
                    169: 
                    170:     err = _eExpMgrConfigReadLong( entryID, offset & (-4), &lvalue);
                    171:     lvalue = (lvalue & ~(0xff << ((offset & 3) * 8))) | (value << ((offset & 3) * 8));
                    172:     err = _eExpMgrConfigWriteLong( entryID, offset & (-4), lvalue);
                    173:     return( err);
                    174: }
                    175: 
                    176: OSStatus _eExpMgrIOReadLong( RegEntryID entryID, UInt16 offset, UInt32 * value )
                    177: {
                    178: 
                    179:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    180: 
                    181:     *value = ioDevice->ioRead32( offset );
                    182: 
                    183:     return( noErr);
                    184: }
                    185: 
                    186: OSStatus _eExpMgrIOWriteLong( RegEntryID entryID, UInt16 offset, UInt32 value )
                    187: {
                    188: 
                    189:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    190: 
                    191:     ioDevice->ioWrite32( offset, value );
                    192: 
                    193:     return( noErr);
                    194: }
                    195: 
                    196: OSStatus _eExpMgrIOReadWord( RegEntryID entryID, UInt16 offset, UInt16 * value )
                    197: {
                    198:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    199: 
                    200:     *value = ioDevice->ioRead16( offset );
                    201: 
                    202:     return( noErr);
                    203: }
                    204: 
                    205: OSStatus _eExpMgrIOWriteWord( RegEntryID entryID, UInt16 offset, UInt16 value )
                    206: {
                    207: 
                    208:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    209: 
                    210:     ioDevice->ioWrite16( offset, value );
                    211: 
                    212:     return( noErr);
                    213: }
                    214: 
                    215: OSStatus _eExpMgrIOReadByte( RegEntryID entryID, UInt16 offset, UInt8 * value )
                    216: {
                    217:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    218: 
                    219:     *value = ioDevice->ioRead8( offset );
                    220: 
                    221:     return( noErr);
                    222: }
                    223: 
                    224: OSStatus _eExpMgrIOWriteByte( RegEntryID entryID, UInt16 offset, UInt8 value )
                    225: {
                    226: 
                    227:     REG_ENTRY_TO_SERVICE( entryID, IOPCIDevice, ioDevice)
                    228: 
                    229:     ioDevice->ioWrite8( offset, value );
                    230: 
                    231:     return( noErr);
                    232: }
                    233: 
                    234: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    235: 
                    236: OSStatus _eRegistryEntryIDCopy( RegEntryID entryID, RegEntryID to )
                    237: {
                    238:     bcopy( entryID, to, sizeof( RegEntryID) );
                    239:     return( noErr);
                    240: }
                    241: 
                    242: 
                    243: OSStatus _eRegistryEntryIDInit( RegEntryID entryID )
                    244: {
                    245:     MAKE_REG_ENTRY( entryID, 0);
                    246:     return( noErr);
                    247: }
                    248: 
                    249: /*
                    250:  * Compare EntryID's for equality or if invalid
                    251:  *
                    252:  * If a NULL value is given for either id1 or id2, the other id 
                    253:  * is compared with an invalid ID.  If both are NULL, the id's 
                    254:  * are consided equal (result = true). 
                    255:  *   note: invalid != uninitialized
                    256:  */
                    257: Boolean _eRegistryEntryIDCompare( RegEntryID entryID1, RegEntryID entryID2 )
                    258: {
                    259:     IORegistryEntry *  regEntry1;
                    260:     IORegistryEntry *  regEntry2;
                    261: 
                    262:     if( entryID1) {
                    263:        REG_ENTRY_TO_OBJ_RET( entryID1, regEntry1, false)
                    264:     } else
                    265:        regEntry1 = 0;
                    266: 
                    267:     if( entryID2) {
                    268:        REG_ENTRY_TO_OBJ_RET( entryID2, regEntry2, false)
                    269:     } else
                    270:        regEntry2 = 0;
                    271: 
                    272:     return( regEntry1 == regEntry2 );
                    273: }
                    274: 
                    275: OSStatus _eRegistryPropertyGetSize( void *entryID, char *propertyName,
                    276:                                        UInt32 * propertySize )
                    277: {
                    278:     OSStatus           err = noErr;
                    279:     OSData *           prop;
                    280: 
                    281:     REG_ENTRY_TO_PT( entryID, regEntry)
                    282: 
                    283:     prop = (OSData *) regEntry->getProperty( propertyName); 
                    284:     if( prop)
                    285:        *propertySize = prop->getLength();
                    286:     else
                    287:        err = nrNotFoundErr;
                    288: 
                    289: #if LOGNAMEREG
                    290:     LOG("RegistryPropertyGetSize: %s : %d\n", propertyName, err);
                    291: #endif
                    292:     return( err);
                    293: 
                    294: }
                    295: 
                    296: OSStatus _eRegistryPropertyGet(void *entryID, char *propertyName, UInt32 *propertyValue, UInt32 *propertySize)
                    297: {
                    298:     OSStatus           err = noErr;
                    299:     OSData *           prop;
                    300:     UInt32             len;
                    301: 
                    302:     REG_ENTRY_TO_PT( entryID, regEntry)
                    303: 
                    304:     prop = OSDynamicCast( OSData, regEntry->getProperty( propertyName));
                    305:     if( prop) {
                    306: 
                    307:        len = *propertySize;
                    308:        *propertySize = prop->getLength();
                    309:        len = (len > prop->getLength()) ? prop->getLength() : len;
                    310:        bcopy( prop->getBytesNoCopy(), propertyValue, len);
                    311: #if LOGNAMEREG
                    312:        LOG("value: %08x ", *propertyValue);
                    313: #endif
                    314:     } else
                    315:        err = nrNotFoundErr;
                    316: 
                    317: #if LOGNAMEREG
                    318:     LOG("RegistryPropertyGet: %s : %d\n", propertyName, err);
                    319: #endif
                    320:     return( err);
                    321: }
                    322: 
                    323: OSStatus _eRegistryPropertyCreate( void *entryID, char *propertyName,
                    324:                                void * propertyValue, UInt32 propertySize )
                    325: {
                    326:     OSStatus           err = noErr;
                    327:     OSData *           prop;
                    328: 
                    329:     REG_ENTRY_TO_PT( entryID, regEntry)
                    330: 
                    331:     prop = OSData::withBytes( propertyValue, propertySize );
                    332: 
                    333:     if( prop) {
                    334: 
                    335:         regEntry->setProperty( propertyName, prop);
                    336:        prop->release();
                    337: 
                    338:     } else
                    339:        err = nrNotCreatedErr;
                    340: 
                    341: #if LOGNAMEREG
                    342:     LOG("RegistryPropertyCreate: %s : %d\n", propertyName, err);
                    343: #endif
                    344:     return( err);
                    345: }
                    346: 
                    347: OSStatus _eRegistryPropertyDelete( void *entryID, char *propertyName )
                    348: {
                    349:     OSStatus           err = noErr;
                    350:     OSObject *         old;
                    351: 
                    352:     REG_ENTRY_TO_PT( entryID, regEntry)
                    353: 
                    354:     old = regEntry->getProperty(propertyName);
                    355:     if ( old )
                    356:         regEntry->removeProperty(propertyName);
                    357:     else
                    358:        err = nrNotFoundErr;
                    359: 
                    360: #if LOGNAMEREG
                    361:     LOG("RegistryPropertyDelete: %s : %d\n", propertyName, err);
                    362: #endif
                    363:     return( err);
                    364: }
                    365: 
                    366: void IONDRVSetNVRAMPropertyName( IORegistryEntry * regEntry,
                    367:                                const OSSymbol * sym )
                    368: {
                    369:     regEntry->setProperty( "IONVRAMProperty", (OSObject *) sym );
                    370: }
                    371: 
                    372: static IOReturn IONDRVSetNVRAMPropertyValue( IORegistryEntry * regEntry,
                    373:                                const OSSymbol * name, OSData * value )
                    374: {
                    375:     IOReturn                   err;
                    376:     IODTPlatformExpert *       platform =
                    377:                 (IODTPlatformExpert *) IOService::getPlatform();
                    378: 
                    379:     err = platform->writeNVRAMProperty( regEntry, name, value );
                    380: 
                    381:     return( err );
                    382: }
                    383: 
                    384: OSStatus _eRegistryPropertySet( void *entryID, char *propertyName, void * propertyValue, UInt32 propertySize )
                    385: {
                    386:     OSStatus                   err = noErr;
                    387:     OSData *                   prop;
                    388:     const OSSymbol *           sym;
                    389: 
                    390:     REG_ENTRY_TO_PT( entryID, regEntry)
                    391: 
                    392:     sym = OSSymbol::withCString( propertyName );
                    393:     if( !sym)
                    394:        return( kIOReturnNoMemory );
                    395: 
                    396:     prop = OSDynamicCast( OSData, regEntry->getProperty( sym ));
                    397:     if( 0 == prop)
                    398:        err = nrNotFoundErr;
                    399: 
                    400:     else if( (prop = OSData::withBytes( propertyValue, propertySize))) {
                    401:         regEntry->setProperty( sym, prop);
                    402: 
                    403:        if( (sym == (const OSSymbol *)
                    404:                regEntry->getProperty("IONVRAMProperty")))
                    405:            err = IONDRVSetNVRAMPropertyValue( regEntry, sym, prop );
                    406:        prop->release();
                    407: 
                    408:     } else
                    409:        err = nrNotCreatedErr;
                    410: 
                    411:     sym->release();
                    412: 
                    413: #if LOGNAMEREG
                    414:     LOG("RegistryPropertySet: %s : %d\n", propertyName, err);
                    415: #endif
                    416:     return( err);
                    417: }
                    418: 
                    419: OSStatus _eRegistryPropertyGetMod(void * entryID, char * propertyName,
                    420:                                 UInt32 * mod)
                    421: {
                    422:     const OSSymbol *   sym;
                    423: 
                    424:     REG_ENTRY_TO_PT( entryID, regEntry)
                    425: 
                    426:     if( (sym = OSDynamicCast( OSSymbol,
                    427:                regEntry->getProperty("IONVRAMProperty")))
                    428:       && (0 == strcmp( propertyName, sym->getCStringNoCopy())))
                    429: 
                    430:        *mod = kNVRAMProperty;
                    431:     else
                    432:        *mod = 0;
                    433: 
                    434:     return( noErr);
                    435: }
                    436: 
                    437: OSStatus _eRegistryPropertySetMod(void *entryID, char *propertyName, 
                    438:                UInt32 mod )
                    439: {
                    440:     OSStatus           err = noErr;
                    441:     OSData *           data;
                    442:     const OSSymbol *   sym;
                    443: 
                    444:     REG_ENTRY_TO_PT( entryID, regEntry)
                    445: 
                    446:     if( (mod & kNVRAMProperty)
                    447:       && (sym = OSSymbol::withCString( propertyName ))) {
                    448: 
                    449:        if( (data = OSDynamicCast( OSData, regEntry->getProperty( sym))) ) {
                    450:            err = IONDRVSetNVRAMPropertyValue( regEntry, sym, data );
                    451:            if( kIOReturnSuccess == err)
                    452:                 IONDRVSetNVRAMPropertyName( regEntry, sym );
                    453:        }
                    454:        sym->release();
                    455:     }
                    456: 
                    457:     return( err);
                    458: }
                    459: 
                    460: 
                    461: OSStatus _eRegistryPropertyIterateCreate( RegEntryID * entryID,
                    462:                                                OSCollectionIterator ** cookie)
                    463: {
                    464: 
                    465:     REG_ENTRY_TO_PT( entryID, regEntry)
                    466: 
                    467:     // NB. unsynchronized. But should only happen on an owned nub!
                    468:     // Should non OSData be filtered out?
                    469:     *cookie = OSCollectionIterator::withCollection(
                    470:                 regEntry->getPropertyTable());
                    471: 
                    472:     if( *cookie)
                    473:        return( noErr);
                    474:     else
                    475:        return( nrNotEnoughMemoryErr);
                    476: }
                    477: 
                    478: OSStatus _eRegistryPropertyIterateDispose( OSCollectionIterator ** cookie)
                    479: {
                    480:     if( *cookie) {
                    481:         (*cookie)->release();
                    482:         *cookie = NULL;
                    483:         return( noErr);
                    484:     } else
                    485:        return( nrIterationDone);
                    486: }
                    487: 
                    488: 
                    489: OSStatus _eRegistryPropertyIterate( OSCollectionIterator ** cookie,
                    490:                                        char * name, Boolean * done )
                    491: {
                    492:     const OSSymbol *   key;
                    493: 
                    494:     key = (const OSSymbol *) (*cookie)->getNextObject();
                    495:     if( key)
                    496:        strncpy( name, key->getCStringNoCopy(), kRegMaximumPropertyNameLength);
                    497: 
                    498:     // Seems to be differences in handling "done".
                    499:     // ATI assumes done = true when getting the last property.
                    500:     // The Book says done is true after last property.
                    501:     // ATI does check err, so this will work.
                    502:     // Control ignores err and checks done.
                    503: 
                    504:     *done = (key == 0);
                    505: 
                    506:     if( 0 != key)
                    507:        return( noErr);
                    508:     else
                    509:        return( nrIterationDone );
                    510: }
                    511: 
                    512: OSStatus
                    513: _eRegistryEntryIterateCreate( IORegistryIterator ** cookie)
                    514: {
                    515:     *cookie = IORegistryIterator::iterateOver( gIODTPlane );
                    516:     if( *cookie)
                    517:        return( noErr);
                    518:     else
                    519:        return( nrNotEnoughMemoryErr);
                    520: }
                    521: 
                    522: OSStatus
                    523: _eRegistryEntryIterateDispose( IORegistryIterator ** cookie)
                    524: {
                    525:     if( *cookie) {
                    526:         (*cookie)->release();
                    527:         *cookie = NULL;
                    528:         return( noErr);
                    529:     } else
                    530:        return( nrIterationDone);
                    531: }
                    532: 
                    533: OSStatus
                    534: _eRegistryEntryIterate( IORegistryIterator **  cookie,
                    535:                        UInt32          /* relationship */,
                    536:                        RegEntryID      foundEntry,
                    537:                        Boolean *       done)
                    538: {
                    539:     IORegistryEntry *  regEntry;
                    540: 
                    541:     // TODO: check requested type of iteration
                    542:     regEntry = (*cookie)->getNextObjectRecursive();
                    543: 
                    544:     MAKE_REG_ENTRY( foundEntry, regEntry);
                    545:     *done = (0 == regEntry);
                    546: 
                    547: #if LOGNAMEREG
                    548:     if( regEntry)
                    549:         LOG("RegistryEntryIterate: %s\n", regEntry->getName( gIODTPlane ));
                    550: #endif
                    551: 
                    552:     if( regEntry)
                    553:        return( noErr);
                    554:     else
                    555:        return( nrNotFoundErr);
                    556: }
                    557: 
                    558: OSStatus
                    559: _eRegistryCStrEntryToName( const RegEntryID *  entryID,
                    560:                        RegEntryID              parentEntry,
                    561:                        char *                  nameComponent,
                    562:                        Boolean *               done )
                    563: {
                    564:     IORegistryEntry *  regEntry;
                    565: 
                    566:     REG_ENTRY_TO_OBJ( entryID, regEntry)
                    567: 
                    568:     strncpy( nameComponent, regEntry->getName( gIODTPlane ), kRegMaximumPropertyNameLength );
                    569:     nameComponent[ kRegMaximumPropertyNameLength ] = 0;
                    570: 
                    571:     regEntry = regEntry->getParentEntry( gIODTPlane );
                    572:     if( regEntry) {
                    573:        MAKE_REG_ENTRY( parentEntry, regEntry);
                    574:        *done = false;
                    575:     } else
                    576:        *done = true;
                    577: 
                    578:     return( noErr);
                    579: }
                    580: 
                    581: OSStatus
                    582: _eRegistryCStrEntryLookup(  const RegEntryID * parentEntry,
                    583:                            const char  *       path,
                    584:                            RegEntryID          newEntry)
                    585: {
                    586:     IOReturn           err;
                    587:     IORegistryEntry *  regEntry;
                    588:     char *             buf;
                    589:     char *             cvtPath;
                    590:     char               c;
                    591: #define kDTRoot        "Devices:device-tree:"
                    592: 
                    593:        return( nrNotEnoughMemoryErr );
                    594: 
                    595:     REG_ENTRY_TO_OBJ( parentEntry, regEntry)
                    596: 
                    597:     IOLog("%s: %s, %s\n", __FUNCTION__, regEntry->getName(), path);
                    598: 
                    599:     buf = IONew( char, 512 );
                    600:     if( !buf)
                    601:        return( nrNotEnoughMemoryErr );
                    602: 
                    603:     cvtPath = buf;
                    604:     if( ':' == path[0])
                    605:        path++;
                    606:     else if( 0 == strncmp( path, kDTRoot, strlen( kDTRoot ))) {
                    607:        path += strlen( kDTRoot ) - 1;
                    608:        regEntry = 0;
                    609:     }
                    610: 
                    611:     do {
                    612:        c = *(path++);
                    613:        if( ':' == c)
                    614:            c = '/';
                    615:        *(cvtPath++) = c;
                    616:     } while( c != 0 );
                    617: 
                    618:     if( regEntry)
                    619:        regEntry = regEntry->childFromPath( buf, gIODTPlane );
                    620:     else
                    621:        regEntry = IORegistryEntry::fromPath( buf, gIODTPlane );
                    622: 
                    623:     if( regEntry) {
                    624:        MAKE_REG_ENTRY( newEntry, regEntry);
                    625:        regEntry->release();
                    626:        err = noErr;
                    627:     } else
                    628:        err = nrNotFoundErr;
                    629: 
                    630:     IODelete( buf, char, 512 );
                    631: 
                    632:     return( err );
                    633: }
                    634: 
                    635: 
                    636: OSStatus
                    637: _eRegistryCStrEntryCreate(  const RegEntryID * parentEntry,
                    638:                            char        *       name,
                    639:                            RegEntryID          newEntry)
                    640: {
                    641:     IORegistryEntry *  newDev;
                    642:     IORegistryEntry *  parent;
                    643: 
                    644:     REG_ENTRY_TO_OBJ( parentEntry, parent)
                    645: 
                    646:     // NOT published
                    647: 
                    648:     newDev = new IORegistryEntry;
                    649:     if( newDev && (false == newDev->init()))
                    650:        newDev = 0;
                    651: 
                    652:     if( newDev) {
                    653:        newDev->attachToParent( parent, gIODTPlane );
                    654:        if( ':' == name[0])
                    655:            name++;
                    656:        newDev->setName( name );
                    657:     }
                    658: 
                    659:     MAKE_REG_ENTRY( newEntry, newDev);
                    660: 
                    661:     if( newDev)
                    662:        return( noErr);
                    663:     else
                    664:        return( nrNotCreatedErr);
                    665: }
                    666: 
                    667: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    668: 
                    669: extern "C" {
                    670: 
                    671: // in NDRVLibrariesAsm.s
                    672: extern void _eSynchronizeIO( void );
                    673: 
                    674: // platform expert
                    675: extern vm_offset_t
                    676: PEResidentAddress( vm_offset_t address, vm_size_t length );
                    677: 
                    678: };
                    679: 
                    680: enum {
                    681:     kProcessorCacheModeDefault         = 0,
                    682:     kProcessorCacheModeInhibited       = 1,
                    683:     kProcessorCacheModeWriteThrough    = 2,
                    684:     kProcessorCacheModeCopyBack                = 3
                    685: };
                    686: 
                    687: OSStatus _eSetProcessorCacheMode( UInt32 /* space */, void * /* addr */,
                    688:                                 UInt32 /* len */, UInt32 /* mode */ )
                    689: {
                    690: #if 0
                    691:     struct phys_entry* pp;
                    692:     vm_offset_t        spa;
                    693:     vm_offset_t        epa;
                    694:     int                        wimg;
                    695: 
                    696:     // This doesn't change any existing kernel mapping eg. BAT changes etc.
                    697:     // but this is enough to change user level mappings for DPS etc.
                    698:     // Should use a kernel service when one is available.
                    699: 
                    700:     spa = kvtophys( (vm_offset_t)addr);
                    701:     if( spa == 0) {
                    702:        spa = PEResidentAddress( (vm_offset_t)addr, len);
                    703:        if( spa == 0)
                    704:            return( kIOReturnVMError);
                    705:     }
                    706:     epa = (len + spa + 0xfff) & 0xfffff000;
                    707:     spa &=  0xfffff000;
                    708: 
                    709:     switch( mode) {
                    710:        case kProcessorCacheModeWriteThrough:
                    711:            wimg = PTE_WIMG_WT_CACHED_COHERENT_GUARDED;
                    712:            break;
                    713:        case kProcessorCacheModeCopyBack:
                    714:            wimg = PTE_WIMG_CB_CACHED_COHERENT_GUARDED;
                    715:            break;
                    716:        default:
                    717:            wimg = PTE_WIMG_UNCACHED_COHERENT_GUARDED;
                    718:            break;
                    719:     }
                    720: 
                    721:     while( spa < epa) {
                    722:        pp = pmap_find_physentry(spa);
                    723:        if (pp != PHYS_NULL)
                    724:            pp->pte1.bits.wimg = wimg;
                    725:        spa += PAGE_SIZE;
                    726:     }
                    727: #endif
                    728:     _eSynchronizeIO();
                    729:     return( noErr);
                    730: }
                    731: 
                    732: char * _ePStrCopy( char *to, const char *from )
                    733: {
                    734:     UInt32     len;
                    735:     char   *   copy;
                    736: 
                    737:     copy = to;
                    738:     len = *(from++);
                    739:     *(copy++) = len;
                    740:     bcopy( from, copy, len);
                    741:     return( to);
                    742: }
                    743: 
                    744: LogicalAddress _ePoolAllocateResident(ByteCount byteSize, Boolean clear)
                    745: {
                    746:     LogicalAddress  mem;
                    747: 
                    748:     mem = (LogicalAddress) kern_os_malloc( (size_t) byteSize );
                    749:     if( clear && mem)
                    750:         memset( mem, 0, byteSize);
                    751: 
                    752:     return( mem);
                    753: }
                    754: 
                    755: OSStatus _ePoolDeallocate( LogicalAddress address )
                    756: {
                    757:     kern_os_free( (void *) address );
                    758:     return( noErr);
                    759: }
                    760: 
                    761: UInt32 _eCurrentExecutionLevel(void)
                    762: {
                    763:        return(0);              // == kTaskLevel, HWInt == 6
                    764: }
                    765: 
                    766: // don't expect any callers of this
                    767: OSErr _eIOCommandIsComplete( UInt32 /* commandID */, OSErr result)
                    768: {
                    769:     LOG("_eIOCommandIsComplete\n");
                    770:     return( result);           // !!??!!
                    771: }
                    772: 
                    773: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    774: 
                    775: #include <kern/clock.h>
                    776: 
                    777: 
                    778: AbsoluteTime _eUpTime( void )
                    779: {
                    780:     AbsoluteTime    result;
                    781: 
                    782:     clock_get_uptime( &result);
                    783: 
                    784:     return( result);
                    785: }
                    786: 
                    787: AbsoluteTime _eAddAbsoluteToAbsolute(AbsoluteTime left, AbsoluteTime right)
                    788: {
                    789:     AbsoluteTime    result = left;
                    790: 
                    791:     ADD_ABSOLUTETIME( &left, &right);
                    792: 
                    793:     return( result);
                    794: }
                    795: 
                    796: 
                    797: AbsoluteTime _eSubAbsoluteFromAbsolute(AbsoluteTime left, AbsoluteTime right)
                    798: {
                    799:     AbsoluteTime    result = left;
                    800: 
                    801:     // !! ATI bug fix here:
                    802:     // They expect the 64-bit result to be signed. The spec says < 0 => 0
                    803:     // To workaround, make sure this routine takes 10 us to execute.
                    804:     IODelay( 10);
                    805: 
                    806:     if( CMP_ABSOLUTETIME( &result, &right) < 0) {
                    807:         AbsoluteTime_to_scalar( &result ) = 0;
                    808:     } else {
                    809:         result = left;
                    810:         SUB_ABSOLUTETIME( &result, &right);
                    811:     }
                    812: 
                    813:     return( result);
                    814: }
                    815: 
                    816: 
                    817: AbsoluteTime    _eDurationToAbsolute( Duration theDuration)
                    818: {
                    819:     AbsoluteTime    result;
                    820: 
                    821:     if( theDuration > 0) {
                    822:         clock_interval_to_absolutetime_interval( theDuration, kMillisecondScale,
                    823:                                                  &result );
                    824: 
                    825:     } else {
                    826:         clock_interval_to_absolutetime_interval( (-theDuration), kMicrosecondScale,
                    827:                                                  &result );
                    828:     }
                    829: 
                    830:     return( result);
                    831: }
                    832: 
                    833: AbsoluteTime _eAddDurationToAbsolute( Duration duration, AbsoluteTime absolute )
                    834: {
                    835:     return( _eAddAbsoluteToAbsolute(_eDurationToAbsolute( duration), absolute));
                    836: }
                    837: 
                    838: #define UnsignedWideToUInt64(x)                (*(UInt64 *)(x))
                    839: #define UInt64ToUnsignedWide(x)                (*(UnsignedWide *)(x))
                    840: 
                    841: AbsoluteTime    _eNanosecondsToAbsolute ( UnsignedWide theNanoseconds)
                    842: {
                    843:     AbsoluteTime result;
                    844:     UInt64     nano = UnsignedWideToUInt64(&theNanoseconds);
                    845: 
                    846:     nanoseconds_to_absolutetime( nano, &result);
                    847: 
                    848:     return( result);
                    849: }
                    850: 
                    851: UnsignedWide    _eAbsoluteToNanoseconds( AbsoluteTime absolute )
                    852: {
                    853:     UnsignedWide result;
                    854:     UInt64     nano;
                    855: 
                    856:     absolutetime_to_nanoseconds( absolute, &nano);
                    857:     result = UInt64ToUnsignedWide( &nano );
                    858: 
                    859:     return( result);
                    860: }
                    861: 
                    862: Duration    _eAbsoluteDeltaToDuration( AbsoluteTime left, AbsoluteTime right )
                    863: {
                    864:     Duration           dur;
                    865:     AbsoluteTime       result;
                    866:     UInt64             nano;
                    867:     
                    868:     if( CMP_ABSOLUTETIME( &left, &right) < 0)
                    869:        return( 0);
                    870: 
                    871:     result = left;
                    872:     SUB_ABSOLUTETIME( &result, &right);
                    873:     absolutetime_to_nanoseconds( result, &nano);
                    874: 
                    875:     if( nano >= ((1ULL << 31) * 1000ULL)) {
                    876:         // +ve milliseconds
                    877:         if( nano >= ((1ULL << 31) * 1000ULL * 1000ULL))
                    878:            dur = 0x7fffffff;
                    879:         else
                    880:             dur = nano / 1000000ULL;
                    881:     } else {
                    882:         // -ve microseconds
                    883:         dur = -(nano / 1000ULL);
                    884:     }
                    885: 
                    886:     return( dur);
                    887: }
                    888: 
                    889: 
                    890: OSStatus    _eDelayForHardware( AbsoluteTime time )
                    891: {
                    892:     AbsoluteTime       deadline;
                    893: 
                    894:     clock_absolutetime_interval_to_deadline( time, &deadline );
                    895:     clock_delay_until( deadline );
                    896: 
                    897:     return( noErr);
                    898: }
                    899: 
                    900: OSStatus    _eDelayFor( Duration theDuration )
                    901: {
                    902: #if 1
                    903: 
                    904: // In Marconi, DelayFor uses the old toolbox Delay routine
                    905: // which is based on the 60 Hz timer. Durations are not
                    906: // rounded up when converting to ticks. Yes, really.
                    907: // Some ATI drivers call DelayFor(1) 50000 times starting up.
                    908: // There is some 64-bit math there so we'd better reproduce
                    909: // the overhead of that calculation.
                    910: 
                    911: #define DELAY_FOR_TICK_NANO            16666666
                    912: #define DELAY_FOR_TICK_MILLI           17
                    913: #define NANO32_MILLI                   4295
                    914: 
                    915:     UnsignedWide       nano;
                    916:     AbsoluteTime       abs;
                    917:     unsigned int       ms;
                    918: 
                    919:     abs = _eDurationToAbsolute( theDuration);
                    920:     nano = _eAbsoluteToNanoseconds( abs);
                    921: 
                    922:     ms = (nano.lo / DELAY_FOR_TICK_NANO) * DELAY_FOR_TICK_MILLI;
                    923:     ms += nano.hi * NANO32_MILLI;
                    924:     if( ms)
                    925:         IOSleep( ms);
                    926: 
                    927: #else
                    928:     // Accurate, but incompatible, version
                    929: 
                    930: #define SLEEP_THRESHOLD                5000
                    931: 
                    932:     if( theDuration < 0) {
                    933: 
                    934:        // us duration
                    935:        theDuration -= theDuration;
                    936:        if( theDuration > SLEEP_THRESHOLD)
                    937:            IOSleep( (theDuration + 999) / 1000);
                    938:        else
                    939:            IODelay( theDuration);
                    940: 
                    941:     } else {
                    942: 
                    943:        // ms duration
                    944:         if( theDuration > (SLEEP_THRESHOLD / 1000))
                    945:             IOSleep( theDuration );                            // ms
                    946:        else
                    947:             IODelay( theDuration * 1000);                      // us
                    948:     }
                    949: #endif
                    950: 
                    951:     return( noErr);
                    952: }
                    953: 
                    954: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                    955: 
                    956: OSStatus _eCallOSTrapUniversalProc( UInt32 /* theProc */,
                    957:                                        UInt32 procInfo, UInt32 trap, UInt8 * pb )
                    958: {
                    959: OSStatus    err = -40;
                    960: 
                    961:     if( (procInfo == 0x133822)
                    962:     &&  (trap == 0xa092) ) {
                    963: 
                    964:        UInt8 addr, reg, data;
                    965: 
                    966:        addr = pb[ 2 ];
                    967:        reg = pb[ 3 ];
                    968:        pb = *( (UInt8 **) ((UInt32) pb + 8));
                    969:        data = pb[ 1 ];
                    970:        (*PE_write_IIC)( addr, reg, data );
                    971:        err = 0;
                    972:     }
                    973:     return( err);
                    974: }
                    975: 
                    976: const UInt32 * _eGetKeys( void )
                    977: {
                    978:     static const UInt32 zeros[] = { 0, 0, 0, 0 };
                    979: 
                    980:     return( zeros);
                    981: }
                    982: 
                    983: UInt32 _eGetIndADB( void * adbInfo, UInt32 /* index */)
                    984: {
                    985:     bzero( adbInfo, 10);
                    986:     return( 0);                // orig address
                    987: }
                    988: 
                    989: char * _eLMGetPowerMgrVars( void )
                    990: {
                    991:     static char * powerMgrVars = NULL;
                    992: 
                    993:     if( powerMgrVars == NULL) {
                    994:        powerMgrVars = (char *) IOMalloc( 0x3c0);
                    995:        if( powerMgrVars)
                    996:            bzero( powerMgrVars, 0x3c0);
                    997:     }
                    998:     return( powerMgrVars);
                    999: }
                   1000: 
                   1001: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1002: 
                   1003: OSStatus _eNoErr( void )
                   1004: {
                   1005:     return( noErr);
                   1006: }
                   1007: 
                   1008: OSStatus _eFail( void )
                   1009: {
                   1010:     return( -40);
                   1011: }
                   1012: 
                   1013: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1014: 
                   1015: // fix this!
                   1016: 
                   1017: #define        heathrowID              ((volatile UInt32 *)0xf3000034)
                   1018: #define        heathrowTermEna         (1 << 3)
                   1019: #define        heathrowTermDir         (1 << 0)
                   1020: 
                   1021: #define        heathrowFeatureControl  ((volatile UInt32 *)0xf3000038)
                   1022: #define        heathrowMBRES           (1 << 24)
                   1023: 
                   1024: #define        heathrowBrightnessControl ((volatile UInt8 *)0xf3000032)
                   1025: #define                defaultBrightness       144
                   1026: #define        heathrowContrastControl ((volatile UInt8 *)0xf3000033)
                   1027: #define                defaultContrast         183
                   1028: 
                   1029: #define        gossamerSystemReg1      ((volatile UInt16 *)0xff000004)
                   1030: #define                gossamerAllInOne        (1 << 4)
                   1031: 
                   1032: void _eATISetMBRES( UInt32 state )
                   1033: {
                   1034:     UInt32     value;
                   1035: 
                   1036:     value = *heathrowFeatureControl;
                   1037: 
                   1038:     if( state == 0)
                   1039:        value &= ~heathrowMBRES;
                   1040:     else if( state == 1)
                   1041:        value |= heathrowMBRES;
                   1042: 
                   1043:     *heathrowFeatureControl = value;
                   1044:     eieio();
                   1045: }
                   1046: 
                   1047: void _eATISetMonitorTermination( Boolean enable )
                   1048: {
                   1049: 
                   1050:     UInt32     value;
                   1051: 
                   1052:     value = *heathrowID;
                   1053: 
                   1054:     value |= heathrowTermEna;
                   1055:     if( enable)
                   1056:        value |= heathrowTermDir;
                   1057:     else
                   1058:        value &= ~heathrowTermDir;
                   1059: 
                   1060:     *heathrowID = value;
                   1061:     eieio();
                   1062: }
                   1063: 
                   1064: Boolean _eATIIsAllInOne( void )
                   1065: {
                   1066:     Boolean    rtn;
                   1067: 
                   1068:     rtn = (0 == ((*gossamerSystemReg1) & gossamerAllInOne));
                   1069:     if( rtn) {
                   1070:        *heathrowBrightnessControl = defaultBrightness;
                   1071:         eieio();
                   1072:        *heathrowContrastControl = defaultContrast;
                   1073:         eieio();
                   1074:     }
                   1075:     return( rtn);
                   1076: }
                   1077: 
                   1078: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1079: 
                   1080: static SInt32 IONDRVStdInterruptHandler( InterruptSetMember setMember,
                   1081:                                        void *refCon, UInt32 theIntCount )
                   1082: {
                   1083: //    assert( false );
                   1084: 
                   1085:     return( kIsrIsComplete );
                   1086: }
                   1087: 
                   1088: static bool IONDRVStdInterruptDisabler( InterruptSetMember setMember,
                   1089:                                        void *refCon )
                   1090: {
                   1091:     IONDRVInterruptSet *       set;
                   1092:     IONDRVInterruptSource *    source;
                   1093:     bool                       was;
                   1094: 
                   1095:     set = (IONDRVInterruptSet *) setMember.setID;
                   1096:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1097:     assert( setMember.member <= set->count );
                   1098:     source = set->sources + setMember.member;
                   1099: 
                   1100:     was = source->enabled;
                   1101:     source->enabled = false;
                   1102: 
                   1103:     assert( set->provider );
                   1104:     set->provider->disableInterrupt( setMember.member - 1 );
                   1105: 
                   1106:     return( was );
                   1107: }
                   1108: 
                   1109: static void IONDRVStdInterruptEnabler( InterruptSetMember setMember,
                   1110:                                        void *refCon )
                   1111: {
                   1112:     IONDRVInterruptSet *       set;
                   1113:     IONDRVInterruptSource *    source;
                   1114: 
                   1115:     set = (IONDRVInterruptSet *) setMember.setID;
                   1116:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1117:     assert( setMember.member <= set->count );
                   1118:     source = set->sources + setMember.member;
                   1119: 
                   1120:     source->enabled = true;
                   1121: 
                   1122:     assert( set->provider );
                   1123:     set->provider->enableInterrupt( setMember.member - 1 );
                   1124: }
                   1125: 
                   1126: static TVector tvIONDRVStdInterruptHandler  = { IONDRVStdInterruptHandler,  0 };
                   1127: static TVector tvIONDRVStdInterruptEnabler  = { IONDRVStdInterruptEnabler,  0 };
                   1128: static TVector tvIONDRVStdInterruptDisabler = { IONDRVStdInterruptDisabler, 0 };
                   1129: 
                   1130: 
                   1131: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1132: 
                   1133: static void IONDRVInterruptAction(     OSObject * target, void * refCon,
                   1134:                                        IOService * provider, int index )
                   1135: {
                   1136:     IONDRVInterruptSet *       set;
                   1137:     IONDRVInterruptSource *    source;
                   1138:     SInt32                     result;
                   1139: 
                   1140:     set = (IONDRVInterruptSet *) target;
                   1141:     index++;
                   1142: 
                   1143:     do {
                   1144: 
                   1145:        assert( (UInt32) index <= set->count);
                   1146:        if( (UInt32) index > set->count)
                   1147:            break;
                   1148: 
                   1149:         source = set->sources + index;
                   1150:         result = CallTVector( set, (void *) index, source->refCon, 0, 0, 0,
                   1151:                                     source->handler );
                   1152: 
                   1153:        switch( result ) {
                   1154: 
                   1155:             case kIsrIsNotComplete:
                   1156:                index++;
                   1157:             case kIsrIsComplete:
                   1158:                break;
                   1159: 
                   1160:             case kMemberNumberParent:
                   1161:                assert( false );
                   1162:                break;
                   1163: 
                   1164:             default:
                   1165:                 index = result;
                   1166:                set = set->child;
                   1167:                break;
                   1168:        }
                   1169: 
                   1170:     } while( result != kIsrIsComplete );
                   1171: }
                   1172: 
                   1173: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1174: 
                   1175: OSStatus
                   1176: _eGetInterruptFunctions(    void *     setID,
                   1177:                            UInt32      member,
                   1178:                            void **     refCon,
                   1179:                            TVector **  handler,
                   1180:                            TVector **  enabler,
                   1181:                            TVector **  disabler )
                   1182: {
                   1183:     IONDRVInterruptSet *       set;
                   1184:     IONDRVInterruptSource *    source;
                   1185:     OSStatus                   err = noErr;
                   1186: 
                   1187:     set = (IONDRVInterruptSet *) setID;
                   1188:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1189:     assert( member <= set->count );
                   1190:     source = set->sources + member;
                   1191: 
                   1192:     if( refCon)
                   1193:        *refCon   = source->refCon;
                   1194:     if( handler)
                   1195:        *handler  = source->handler;
                   1196:     if( enabler)
                   1197:        *enabler  = source->enabler;
                   1198:     if( disabler)
                   1199:        *disabler = source->disabler;
                   1200: 
                   1201:     return( err);
                   1202: }
                   1203: 
                   1204: OSStatus
                   1205: _eInstallInterruptFunctions(void *     setID,
                   1206:                            UInt32      member,
                   1207:                            void *      refCon,
                   1208:                            TVector *   handler,
                   1209:                            TVector *   enabler,
                   1210:                            TVector *   disabler )
                   1211: {
                   1212:     IONDRVInterruptSet *       set;
                   1213:     IONDRVInterruptSource *    source;
                   1214:     OSStatus                   err = noErr;
                   1215: 
                   1216:     set = (IONDRVInterruptSet *) setID;
                   1217:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1218:     assert( member <= set->count );
                   1219:     source = set->sources + member;
                   1220: 
                   1221:     source->refCon = refCon;
                   1222:     if( handler)
                   1223:        source->handler  = handler;
                   1224:     if( enabler)
                   1225:        source->enabler  = enabler;
                   1226:     if( disabler)
                   1227:        source->disabler = disabler;
                   1228: 
                   1229:     return( err);
                   1230: }
                   1231: 
                   1232: OSStatus
                   1233: _eCreateInterruptSet(  void *          parentSet,
                   1234:                        UInt32          parentMember,
                   1235:                        UInt32          setSize,
                   1236:                        void **         setID,
                   1237:                        IOOptionBits    options )
                   1238: {
                   1239:     IONDRVInterruptSet *       set;
                   1240:     IONDRVInterruptSet *       newSet;
                   1241:     IONDRVInterruptSource *    source;
                   1242:     OSStatus                   err = noErr;
                   1243: 
                   1244:     set = (IONDRVInterruptSet *) parentSet;
                   1245:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1246:     assert( parentMember <= set->count );
                   1247:     source = set->sources + parentMember;
                   1248: 
                   1249:     newSet = IONDRVInterruptSet::with( 0, options, setSize );
                   1250:     assert( newSet );
                   1251: 
                   1252:     if( newSet) for( UInt32 i = 1; i <= setSize; i++ ) {
                   1253: 
                   1254:        source = newSet->sources + i;
                   1255:        source->handler         = &tvIONDRVStdInterruptHandler;
                   1256:        source->enabler         = &tvIONDRVStdInterruptEnabler;
                   1257:        source->disabler        = &tvIONDRVStdInterruptDisabler;
                   1258:     }
                   1259: 
                   1260:     set->child = newSet;
                   1261:     *setID = newSet;
                   1262: 
                   1263:     return( err );
                   1264: }
                   1265: 
                   1266: OSStatus 
                   1267: _eDeleteInterruptSet(  void *          setID )
                   1268: {
                   1269:     IONDRVInterruptSet *       set;
                   1270:     OSStatus                   err = noErr;
                   1271: 
                   1272:     set = (IONDRVInterruptSet *) setID;
                   1273:     assert( OSDynamicCast( IONDRVInterruptSet, set ));
                   1274: 
                   1275:     set->release();
                   1276: 
                   1277:     return( err );
                   1278: }
                   1279: 
                   1280: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1281: 
                   1282: #define MAKEFUNC(s,e) { s, e, 0 }
                   1283: 
                   1284: static FunctionEntry PCILibFuncs[] =
                   1285: {
                   1286:     MAKEFUNC( "ExpMgrConfigReadLong", _eExpMgrConfigReadLong),
                   1287:     MAKEFUNC( "ExpMgrConfigReadWord", _eExpMgrConfigReadWord),
                   1288:     MAKEFUNC( "ExpMgrConfigReadByte", _eExpMgrConfigReadByte),
                   1289:     MAKEFUNC( "ExpMgrConfigWriteLong", _eExpMgrConfigWriteLong),
                   1290:     MAKEFUNC( "ExpMgrConfigWriteWord", _eExpMgrConfigWriteWord),
                   1291:     MAKEFUNC( "ExpMgrConfigWriteByte", _eExpMgrConfigWriteByte),
                   1292: 
                   1293:     MAKEFUNC( "ExpMgrIOReadLong", _eExpMgrIOReadLong),
                   1294:     MAKEFUNC( "ExpMgrIOReadWord", _eExpMgrIOReadWord),
                   1295:     MAKEFUNC( "ExpMgrIOReadByte", _eExpMgrIOReadByte),
                   1296:     MAKEFUNC( "ExpMgrIOWriteLong", _eExpMgrIOWriteLong),
                   1297:     MAKEFUNC( "ExpMgrIOWriteWord", _eExpMgrIOWriteWord),
                   1298:     MAKEFUNC( "ExpMgrIOWriteByte", _eExpMgrIOWriteByte),
                   1299: 
                   1300:     MAKEFUNC( "EndianSwap16Bit", _eEndianSwap16Bit),
                   1301:     MAKEFUNC( "EndianSwap32Bit", _eEndianSwap32Bit)
                   1302: };
                   1303: 
                   1304: static FunctionEntry VideoServicesLibFuncs[] =
                   1305: {
                   1306:     MAKEFUNC( "VSLPrepareCursorForHardwareCursor",
                   1307:                IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor),
                   1308:     MAKEFUNC( "VSLNewInterruptService", IONDRVFramebuffer::VSLNewInterruptService),
                   1309:     MAKEFUNC( "VSLDisposeInterruptService", IONDRVFramebuffer::VSLDisposeInterruptService),
                   1310:     MAKEFUNC( "VSLDoInterruptService", IONDRVFramebuffer::VSLDoInterruptService)
                   1311: };
                   1312: 
                   1313: static FunctionEntry NameRegistryLibFuncs[] =
                   1314: {
                   1315:     MAKEFUNC( "RegistryEntryIDCopy", _eRegistryEntryIDCopy),
                   1316:     MAKEFUNC( "RegistryEntryIDInit", _eRegistryEntryIDInit),
                   1317:     MAKEFUNC( "RegistryEntryIDDispose", _eNoErr),
                   1318:     MAKEFUNC( "RegistryEntryIDCompare", _eRegistryEntryIDCompare),
                   1319:     MAKEFUNC( "RegistryPropertyGetSize", _eRegistryPropertyGetSize),
                   1320:     MAKEFUNC( "RegistryPropertyGet", _eRegistryPropertyGet),
                   1321:     MAKEFUNC( "RegistryPropertyGetMod", _eRegistryPropertyGetMod),
                   1322:     MAKEFUNC( "RegistryPropertySetMod", _eRegistryPropertySetMod),
                   1323: 
                   1324:     MAKEFUNC( "RegistryPropertyIterateCreate", _eRegistryPropertyIterateCreate),
                   1325:     MAKEFUNC( "RegistryPropertyIterateDispose", _eRegistryPropertyIterateDispose),
                   1326:     MAKEFUNC( "RegistryPropertyIterate", _eRegistryPropertyIterate),
                   1327: 
                   1328:     MAKEFUNC( "RegistryEntryIterateCreate", _eRegistryEntryIterateCreate),
                   1329:     MAKEFUNC( "RegistryEntryIterateDispose", _eRegistryEntryIterateDispose),
                   1330:     MAKEFUNC( "RegistryEntryIterate", _eRegistryEntryIterate),
                   1331:     MAKEFUNC( "RegistryCStrEntryToName", _eRegistryCStrEntryToName),
                   1332:     MAKEFUNC( "RegistryCStrEntryLookup", _eRegistryCStrEntryLookup),
                   1333: 
                   1334:     MAKEFUNC( "RegistryCStrEntryCreate", _eRegistryCStrEntryCreate),
                   1335:     MAKEFUNC( "RegistryEntryDelete", _eNoErr),
                   1336: 
                   1337:     MAKEFUNC( "RegistryPropertyCreate", _eRegistryPropertyCreate),
                   1338:     MAKEFUNC( "RegistryPropertyDelete", _eRegistryPropertyDelete),
                   1339:     MAKEFUNC( "RegistryPropertySet", _eRegistryPropertySet)
                   1340: };
                   1341: 
                   1342: 
                   1343: static FunctionEntry DriverServicesLibFuncs[] =
                   1344: {
                   1345:     MAKEFUNC( "SynchronizeIO", _eSynchronizeIO),
                   1346:     MAKEFUNC( "SetProcessorCacheMode", _eSetProcessorCacheMode),
                   1347:     MAKEFUNC( "BlockCopy", bcopy),
                   1348:     MAKEFUNC( "BlockMove", bcopy),
                   1349:     MAKEFUNC( "CStrCopy", strcpy),
                   1350:     MAKEFUNC( "CStrCmp", strcmp),
                   1351:     MAKEFUNC( "CStrLen", strlen),
                   1352:     MAKEFUNC( "CStrCat", strcat),
                   1353:     MAKEFUNC( "CStrNCopy", strncpy),
                   1354:     MAKEFUNC( "CStrNCmp", strncmp),
                   1355:     MAKEFUNC( "CStrNCat", strncat),
                   1356:     MAKEFUNC( "PStrCopy", _ePStrCopy),
                   1357: 
                   1358:     MAKEFUNC( "PoolAllocateResident", _ePoolAllocateResident),
                   1359:     MAKEFUNC( "MemAllocatePhysicallyContiguous", _ePoolAllocateResident),
                   1360:     MAKEFUNC( "PoolDeallocate", _ePoolDeallocate),
                   1361: 
                   1362:     MAKEFUNC( "UpTime", _eUpTime),
                   1363:     MAKEFUNC( "AbsoluteDeltaToDuration", _eAbsoluteDeltaToDuration),
                   1364:     MAKEFUNC( "AddAbsoluteToAbsolute", _eAddAbsoluteToAbsolute),
                   1365:     MAKEFUNC( "SubAbsoluteFromAbsolute", _eSubAbsoluteFromAbsolute),
                   1366:     MAKEFUNC( "AddDurationToAbsolute", _eAddDurationToAbsolute),
                   1367:     MAKEFUNC( "NanosecondsToAbsolute", _eNanosecondsToAbsolute),
                   1368:     MAKEFUNC( "AbsoluteToNanoseconds", _eAbsoluteToNanoseconds),
                   1369:     MAKEFUNC( "DurationToAbsolute", _eDurationToAbsolute),
                   1370:     MAKEFUNC( "DelayForHardware", _eDelayForHardware),
                   1371:     MAKEFUNC( "DelayFor", _eDelayFor),
                   1372: 
                   1373:     MAKEFUNC( "CurrentExecutionLevel", _eCurrentExecutionLevel),
                   1374:     MAKEFUNC( "IOCommandIsComplete", _eIOCommandIsComplete),
                   1375: 
                   1376:     MAKEFUNC( "SysDebugStr", _eNoErr),
                   1377:     MAKEFUNC( "SysDebug", _eNoErr),
                   1378: 
                   1379:     MAKEFUNC( "CompareAndSwap", OSCompareAndSwap),
                   1380: 
                   1381:     MAKEFUNC( "CreateInterruptSet", _eCreateInterruptSet),
                   1382:     MAKEFUNC( "DeleteInterruptSet", _eDeleteInterruptSet),
                   1383:     MAKEFUNC( "GetInterruptFunctions", _eGetInterruptFunctions),
                   1384:     MAKEFUNC( "InstallInterruptFunctions", _eInstallInterruptFunctions)
                   1385: 
                   1386: };
                   1387: 
                   1388: static FunctionEntry ATIUtilsFuncs[] =
                   1389: {
                   1390:     // Gossamer onboard ATI
                   1391:     MAKEFUNC( "ATISetMBRES", _eATISetMBRES),
                   1392:     MAKEFUNC( "ATISetMonitorTermination", _eATISetMonitorTermination),
                   1393:     MAKEFUNC( "ATIIsAllInOne", _eATIIsAllInOne)
                   1394: };
                   1395: 
                   1396: // These are all out of spec
                   1397: 
                   1398: static FunctionEntry InterfaceLibFuncs[] =
                   1399: {
                   1400:     // Apple control : XPRam and EgretDispatch
                   1401:     MAKEFUNC( "CallUniversalProc", _eFail),
                   1402:     MAKEFUNC( "CallOSTrapUniversalProc", _eCallOSTrapUniversalProc),
                   1403: 
                   1404:     // Apple chips65550
                   1405: //    MAKEFUNC( "NewRoutineDescriptor", _eCallOSTrapUniversalProc),
                   1406: //    MAKEFUNC( "DisposeRoutineDescriptor", _eNoErr),
                   1407: //    MAKEFUNC( "InsTime", _eInsTime),
                   1408: //    MAKEFUNC( "PrimeTime", _ePrimeTime),
                   1409: 
                   1410:     // Radius PrecisionColor 16
                   1411:     MAKEFUNC( "CountADBs", _eNoErr),
                   1412:     MAKEFUNC( "GetIndADB", _eGetIndADB),
                   1413:     MAKEFUNC( "GetKeys", _eGetKeys)
                   1414: };
                   1415: 
                   1416: static FunctionEntry PrivateInterfaceLibFuncs[] =
                   1417: {
                   1418:     // Apple chips65550
                   1419:     MAKEFUNC( "LMGetPowerMgrVars", _eLMGetPowerMgrVars )
                   1420: };
                   1421: 
                   1422: #define NUMLIBRARIES   7
                   1423: const ItemCount IONumNDRVLibraries = NUMLIBRARIES;
                   1424: LibraryEntry IONDRVLibraries[ NUMLIBRARIES ] =
                   1425: {
                   1426:     { "PCILib", sizeof(PCILibFuncs) / sizeof(FunctionEntry), PCILibFuncs },
                   1427:     { "VideoServicesLib", sizeof(VideoServicesLibFuncs) / sizeof(FunctionEntry), VideoServicesLibFuncs },
                   1428:     { "NameRegistryLib", sizeof(NameRegistryLibFuncs) / sizeof(FunctionEntry), NameRegistryLibFuncs },
                   1429:     { "DriverServicesLib", sizeof(DriverServicesLibFuncs) / sizeof(FunctionEntry), DriverServicesLibFuncs },
                   1430: 
                   1431:     // G3
                   1432:     { "ATIUtils", sizeof(ATIUtilsFuncs) / sizeof(FunctionEntry), ATIUtilsFuncs },
                   1433: 
                   1434:     // out of spec stuff
                   1435:     { "InterfaceLib", sizeof(InterfaceLibFuncs) / sizeof(FunctionEntry), InterfaceLibFuncs },
                   1436:     { "PrivateInterfaceLib", sizeof(PrivateInterfaceLibFuncs) / sizeof(FunctionEntry), PrivateInterfaceLibFuncs }
                   1437: };
                   1438: 
                   1439: } /* extern "C" */
                   1440: 
                   1441: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1442: 
                   1443: #define super OSObject
                   1444: 
                   1445: OSDefineMetaClassAndStructors(IONDRVInterruptSet, OSObject)
                   1446: 
                   1447: IONDRVInterruptSet * IONDRVInterruptSet::with(IOService * provider,
                   1448:                                     IOOptionBits options, SInt32 count )
                   1449: {
                   1450:     IONDRVInterruptSet * set;
                   1451: 
                   1452:     set = new IONDRVInterruptSet;
                   1453:     if( set && !set->init()) {
                   1454:        set->release();
                   1455:        set = 0;
                   1456:     }
                   1457: 
                   1458:     if( set) {
                   1459: 
                   1460:        set->provider   = provider;
                   1461:        set->options    = options;
                   1462:        set->count      = count;
                   1463: 
                   1464:        count++;
                   1465:        set->sources = IONew( IONDRVInterruptSource, count );
                   1466:        assert( set->sources );
                   1467:        bzero( set->sources, count * sizeof( IONDRVInterruptSource));
                   1468:     }
                   1469: 
                   1470:     return( set );
                   1471: }
                   1472: 
                   1473: void IONDRVInterruptSet::free()
                   1474: {
                   1475:     if( sources)
                   1476:        IODelete( sources, IONDRVInterruptSource, count + 1 );
                   1477: 
                   1478:     super::free();
                   1479: }
                   1480: 
                   1481: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1482: 
                   1483: #if NDRVLIBTEST
                   1484: 
                   1485: static void IONDRVLibrariesTest( IOService * provider )
                   1486: {
                   1487:     UInt64 nano;
                   1488:     UnsignedWide nano2;
                   1489:     AbsoluteTime abs1, abs2;
                   1490: 
                   1491:     nano = 1000ULL;
                   1492:     abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
                   1493:     IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
                   1494:     nano2 = _eAbsoluteToNanoseconds(abs1);
                   1495:     IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
                   1496:     AbsoluteTime_to_scalar(&abs2) = 0;
                   1497:     IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
                   1498: 
                   1499:     nano = 0x13161b000ULL;
                   1500:     abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
                   1501:     IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
                   1502:     nano2 = _eAbsoluteToNanoseconds(abs1);
                   1503:     IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
                   1504:     AbsoluteTime_to_scalar(&abs2) = 0;
                   1505:     IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
                   1506: 
                   1507:     nano = 0x6acfc00000000ULL;
                   1508:     abs1 = _eNanosecondsToAbsolute(UInt64ToUnsignedWide(&nano));
                   1509:     IOLog("_eNanosecondsToAbsolute %08lx:%08lx\n", abs1.hi, abs1.lo);
                   1510:     nano2 = _eAbsoluteToNanoseconds(abs1);
                   1511:     IOLog("_eAbsoluteToNanoseconds %08lx:%08lx\n", nano2.hi, nano2.lo);
                   1512:     AbsoluteTime_to_scalar(&abs2) = 0;
                   1513:     IOLog("_eAbsoluteDeltaToDuration %ld\n", _eAbsoluteDeltaToDuration(abs1,abs2));
                   1514: 
                   1515:     abs1 = _eUpTime();
                   1516:     IODelay(10);
                   1517:     abs2 = _eUpTime();
                   1518:     IOLog("10us duration %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
                   1519: 
                   1520:     abs1 = _eUpTime();
                   1521:     for( int i =0; i < 50000; i++)
                   1522:         _eDelayFor(1);
                   1523:     abs2 = _eUpTime();
                   1524:     IOLog("50000 DelayFor(1) %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
                   1525: 
                   1526:     abs1 = _eUpTime();
                   1527:     _eDelayFor(50);
                   1528:     abs2 = _eUpTime();
                   1529:     IOLog("DelayFor(50) %ld\n", _eAbsoluteDeltaToDuration(abs2,abs1));
                   1530: 
                   1531:     abs1 = _eDurationToAbsolute( -10);
                   1532:     IOLog("_eDurationToAbsolute(-10) %08lx:%08lx\n", abs1.hi, abs1.lo);
                   1533:     abs1 = _eDurationToAbsolute( 10);
                   1534:     IOLog("_eDurationToAbsolute(10) %08lx:%08lx\n", abs1.hi, abs1.lo);
                   1535: 
                   1536: }
                   1537: #endif
                   1538: 
                   1539: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
                   1540: 
                   1541: IOReturn IONDRVLibrariesInitialize( IOService * provider )
                   1542: {
                   1543:     IODTPlatformExpert *       platform;
                   1544:     const OSSymbol *           sym;
                   1545:     OSData *                   data;
                   1546:     OSArray *                  intSpec;
                   1547:     unsigned int               len, i;
                   1548: 
                   1549: #if NDRVLIBTEST
                   1550:     IONDRVLibrariesTest( provider );
                   1551: #endif
                   1552: 
                   1553:     // copy nvram property
                   1554: 
                   1555:     if( (platform = OSDynamicCast( IODTPlatformExpert,
                   1556:             IOService::getPlatform()))) {
                   1557: 
                   1558: //     IOService::waitForService( IOService::resourceMatching( "IONVRAM" ));
                   1559: 
                   1560:         if( kIOReturnSuccess == platform->readNVRAMProperty( provider,
                   1561:                                                        &sym, &data )) {
                   1562: 
                   1563:             IONDRVSetNVRAMPropertyName( provider, sym );
                   1564:             provider->setProperty( sym, data);
                   1565:             data->release();
                   1566:             sym->release();
                   1567:         }
                   1568:     }
                   1569: 
                   1570:     // create interrupt properties, if none present
                   1571: 
                   1572:     if( (intSpec = (OSArray *)provider->getProperty( gIOInterruptSpecifiersKey))
                   1573:      && (0 == provider->getProperty( gIODTAAPLInterruptsKey ))) {
                   1574:         // make AAPL,interrupts property if not present (NW)
                   1575:         for( i = 0, len = 0; i < intSpec->getCount(); i++ ) {
                   1576:             data = (OSData *) intSpec->getObject(i);
                   1577:             assert( data );
                   1578:             len += data->getLength();
                   1579:         }
                   1580:         if( len)
                   1581:             data = OSData::withCapacity( len );
                   1582:         if( data) {
                   1583:             for( i = 0; i < intSpec->getCount(); i++ )
                   1584:                 data->appendBytes( (OSData *) intSpec->getObject(i));
                   1585:             provider->setProperty( gIODTAAPLInterruptsKey, data );
                   1586:             data->release();
                   1587:         }
                   1588:     }
                   1589: 
                   1590:     // make NDRV interrupts
                   1591: 
                   1592:     data = OSData::withCapacity( kISTPropertyMemberCount
                   1593:                                 * sizeof( InterruptSetMember));
                   1594: 
                   1595:     InterruptSetMember                 setMember;
                   1596:     IONDRVInterruptSet *       set;
                   1597:     IONDRVInterruptSource *    source;
                   1598: 
                   1599:     set = IONDRVInterruptSet::with( provider, 0,
                   1600:                                kISTPropertyMemberCount );
                   1601: 
                   1602:     if( set) for( i = 1; i <= kISTPropertyMemberCount; i++ ) {
                   1603: 
                   1604:        source = set->sources + i;
                   1605:        source->handler         = &tvIONDRVStdInterruptHandler;
                   1606:        source->enabler         = &tvIONDRVStdInterruptEnabler;
                   1607:        source->disabler        = &tvIONDRVStdInterruptDisabler;
                   1608: 
                   1609:        setMember.setID         = (void *) set;
                   1610:        setMember.member        = i;
                   1611:        data->appendBytes( &setMember, sizeof( setMember));
                   1612: 
                   1613:        provider->registerInterrupt( i - 1, set,
                   1614:                                &IONDRVInterruptAction, (void *) 0x53 );
                   1615:     } else
                   1616:        data = 0;
                   1617: 
                   1618:     if( data) {
                   1619:         provider->setProperty( kISTPropertyName, data );
                   1620:         data->release();
                   1621:         data = 0;
                   1622:     }
                   1623: 
                   1624:     // map memory
                   1625: 
                   1626:     IOItemCount        numMaps = provider->getDeviceMemoryCount();
                   1627:     IOVirtualAddress   virtAddress;
                   1628: 
                   1629:     for( i = 0; i < numMaps; i++) {
                   1630:         IODeviceMemory *       mem;
                   1631:         IOMemoryMap *  map;
                   1632:         bool           consoleDevice;
                   1633: 
                   1634:         consoleDevice = (0 != provider->getProperty("AAPL,boot-display"));
                   1635: 
                   1636:         mem = provider->getDeviceMemoryWithIndex( i );
                   1637:         if( 0 == mem)
                   1638:             continue;
                   1639: 
                   1640:               // set up a 1-1 mapping for the BAT map of the console device
                   1641:               // remove this soon
                   1642:         if( consoleDevice && (0 == mem->map( kIOMapReference)))
                   1643:             mem->setMapping( kernel_task, mem->getPhysicalAddress() );
                   1644: 
                   1645:         map = mem->map();
                   1646:         if( 0 == map) {
                   1647: //             IOLog("%s: map[%ld] failed\n", provider->getName(), i);
                   1648:             continue;
                   1649:         }
                   1650: 
                   1651:         virtAddress = map->getVirtualAddress();
                   1652:         if( !data)
                   1653:             data = OSData::withCapacity( numMaps * sizeof( IOVirtualAddress));
                   1654:         if( !data)
                   1655:             continue;
                   1656:         data->appendBytes( &virtAddress, sizeof( IOVirtualAddress));
                   1657:         kprintf("ndrv base = %lx\n", virtAddress);
                   1658:     }
                   1659: 
                   1660:     // NDRV aperture vectors
                   1661:     if( data) {
                   1662:         provider->setProperty( "AAPL,address", data );
                   1663:         data->release();
                   1664:     }
                   1665: 
                   1666:     return( kIOReturnSuccess );
                   1667: }
                   1668: 

unix.superglobalmegacorp.com

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