Annotation of XNU/iokit/Families/IONDRVSupport/IONDRVFramebuffer.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:  * Copyright (c) 1997-1998 Apple Computer, Inc.
        !            24:  *
        !            25:  *
        !            26:  * HISTORY
        !            27:  *
        !            28:  * sdouglas  22 Oct 97 - first checked in.
        !            29:  * sdouglas  24 Jul 98 - start IOKit.
        !            30:  * sdouglas  15 Dec 98 - cpp.
        !            31:  *
        !            32:  */
        !            33: 
        !            34: #include <IOKit/IOLib.h>
        !            35: #include <IOKit/IOPlatformExpert.h>
        !            36: #include <IOKit/IODeviceTreeSupport.h>
        !            37: #include <IOKit/IOLocks.h>
        !            38: #include <IOKit/ndrvsupport/IONDRVFramebuffer.h>
        !            39: #include <IOKit/assert.h>
        !            40: 
        !            41: #include <libkern/c++/OSContainers.h>
        !            42: 
        !            43: #include "IONDRV.h"
        !            44: 
        !            45: #include <string.h>
        !            46: 
        !            47: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            48: 
        !            49: class IOATINDRV : public IONDRVFramebuffer
        !            50: {
        !            51:     OSDeclareDefaultStructors(IOATINDRV)
        !            52: 
        !            53: public:
        !            54:     virtual IOReturn getStartupDisplayMode( IODisplayModeID * displayMode,
        !            55:                             IOIndex * depth );
        !            56:     virtual IODeviceMemory * findVRAM( void );
        !            57: 
        !            58: };
        !            59: 
        !            60: class IOATI128NDRV : public IOATINDRV
        !            61: {
        !            62:     OSDeclareDefaultStructors(IOATI128NDRV)
        !            63: 
        !            64: public:
        !            65:     virtual void flushCursor( void );
        !            66: };
        !            67: 
        !            68: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            69: 
        !            70: struct _VSLService {
        !            71:     class IONDRVFramebuffer *  framebuffer;
        !            72:     IOSelect                   type;
        !            73:     IOFBInterruptProc                  handler;
        !            74:     OSObject *                 target;
        !            75:     void *                     ref;
        !            76:     _VSLService *              next;
        !            77: };
        !            78: 
        !            79: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            80: 
        !            81: // frame buffer has two power states, off and on
        !            82: #define number_of_power_states 2
        !            83: 
        !            84: static IOPMPowerState ourPowerStates[number_of_power_states] = {
        !            85:   {1,0,0,0,0,0,0,0,0,0,0,0},
        !            86:   {1,IOPMDeviceUsable,IOPMPowerOn,IOPMPowerOn,0,0,0,0,0,0,0,0}
        !            87: };
        !            88: 
        !            89: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            90: 
        !            91: #define super IOFramebuffer
        !            92: 
        !            93: OSDefineMetaClassAndStructors(IONDRVFramebuffer, IOFramebuffer)
        !            94: 
        !            95: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !            96: 
        !            97: //============
        !            98: //= External =
        !            99: //============
        !           100: 
        !           101: IOService * IONDRVFramebuffer::probe( IOService *      provider,
        !           102:                                         SInt32 *       score )
        !           103: {
        !           104:     IOService *                inst = this;
        !           105:     IOService *                newInst = 0;
        !           106:     const char *       name;
        !           107: 
        !           108:     if( !super::probe( provider, score ))
        !           109:        return( 0 );
        !           110: 
        !           111:     if( IONDRV::fromRegistryEntry( provider )) {
        !           112: 
        !           113:         // temporary for in-kernel acceleration
        !           114:         name = provider->getName();
        !           115:         if( 0 == strncmp("ATY,Rage128", name, strlen("ATY,Rage128")))
        !           116:             newInst = new IOATI128NDRV;
        !           117:         else if( 0 == strncmp("ATY,", name, strlen("ATY,")))
        !           118:             newInst = new IOATINDRV;
        !           119: 
        !           120:        if( newInst) {
        !           121:             if( ! newInst->init( inst->getPropertyTable())) {
        !           122:                 newInst->release();
        !           123:                 newInst = 0;
        !           124:             }
        !           125:            inst = newInst;
        !           126:        }
        !           127:     } else
        !           128:        inst = 0;
        !           129: 
        !           130:     return( inst );
        !           131: }
        !           132: 
        !           133: bool IONDRVFramebuffer::start( IOService * provider )
        !           134: {
        !           135:     bool               ok = false;
        !           136:     IOService *                parent;
        !           137:     
        !           138:     do {
        !           139:        nub = provider;
        !           140:         ndrv = IONDRV::fromRegistryEntry( provider );
        !           141:        if( 0 == ndrv)
        !           142:            continue;
        !           143: 
        !           144:        setName( ndrv->driverName());
        !           145:        startAt8 = 3;
        !           146:         consoleDevice = (0 != provider->getProperty("AAPL,boot-display"));
        !           147: 
        !           148:         if( 0 == nub->getDeviceMemoryCount()) {
        !           149:             parent = OSDynamicCast( IOService, nub->getParentEntry(gIODTPlane));
        !           150:             if( parent) {
        !           151:                 parent->getResources();
        !           152:                 OSArray * array = parent->getDeviceMemory();
        !           153:                 array->retain();
        !           154:                 nub->setDeviceMemory( array);
        !           155:                 array->release();
        !           156:             }
        !           157:         }
        !           158: 
        !           159:         if( false == super::start( nub ))
        !           160:            continue;
        !           161: 
        !           162:        ok = true;                      // Success
        !           163: 
        !           164:     } while( false);
        !           165:     
        !           166:     return( ok);
        !           167: }
        !           168: 
        !           169: bool IONDRVFramebuffer::isConsoleDevice( void )
        !           170: {
        !           171:     return( consoleDevice );
        !           172: }
        !           173: 
        !           174: // osfmk/ppc/mappings.h
        !           175: extern "C" { extern void ignore_zero_fault(boolean_t); }
        !           176: 
        !           177: IOReturn IONDRVFramebuffer::enableController( void )
        !           178: {
        !           179:     IOReturn           err;
        !           180:     const char *       logname;
        !           181:     
        !           182:     logname = getProvider()->getName();
        !           183: 
        !           184:     if( 0 == strcmp( "control", logname))
        !           185:         waitForService( resourceMatching( "IOiic0" ));
        !           186: 
        !           187:     err = IONDRVLibrariesInitialize( getProvider() );
        !           188: 
        !           189:     if( kIOReturnSuccess == err) do {
        !           190: 
        !           191:         ignore_zero_fault( true );
        !           192:        err = checkDriver();
        !           193:         ignore_zero_fault( false );
        !           194: 
        !           195:         if( err) {
        !           196:             IOLog("%s: Not usable\n", logname );
        !           197:             if( err == -999)
        !           198:                 IOLog("%s: driver incompatible.\n", logname );
        !           199:             continue;
        !           200:         }
        !           201:         getCurrentConfiguration();
        !           202:         vramMemory = findVRAM();
        !           203: 
        !           204:     } while( false);
        !           205: 
        !           206:     // initialize power management of the device
        !           207:     initForPM();
        !           208:     
        !           209:     return( err);
        !           210: }
        !           211: 
        !           212: IODeviceMemory * IONDRVFramebuffer::getVRAMRange( void )
        !           213: {
        !           214:     if( vramMemory)
        !           215:        vramMemory->retain();
        !           216: 
        !           217:     return( vramMemory );
        !           218: }
        !           219: 
        !           220: void IONDRVFramebuffer::free( void )
        !           221: {
        !           222:     super::free();
        !           223: }
        !           224: 
        !           225: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           226: 
        !           227: IOReturn IONDRVFramebuffer::registerForInterruptType( IOSelect interruptType,
        !           228:                         IOFBInterruptProc proc, OSObject * target, void * ref,
        !           229:                        void ** interruptRef )
        !           230: 
        !           231: {
        !           232:     _VSLService *      service;
        !           233:     IOReturn           err;
        !           234: 
        !           235:     if( (interruptType == kIOFBVBLInterruptType)
        !           236:         && (getProvider()->getProperty("Ignore VBL")))
        !           237:        return( kIOReturnUnsupported );
        !           238: 
        !           239:     for( service = vslServices;
        !           240:         service && (service->type != interruptType);
        !           241:         service = service->next ) {}
        !           242: 
        !           243:     if( service) {
        !           244: 
        !           245:        if( service->handler)
        !           246:            err = kIOReturnBusy;
        !           247: 
        !           248:        else {
        !           249:            service->target     = target;
        !           250:            service->ref        = ref;
        !           251:            service->handler    = proc;
        !           252:            *interruptRef = service;
        !           253:            err = kIOReturnSuccess;
        !           254:        }
        !           255: 
        !           256:     } else
        !           257:        err = kIOReturnNoResources;
        !           258: 
        !           259:     return( err );
        !           260: }
        !           261: 
        !           262: IOReturn IONDRVFramebuffer::unregisterInterrupt( void * interruptRef )
        !           263: {
        !           264:     _VSLService *      service = (_VSLService *) interruptRef;
        !           265: 
        !           266:     service->handler = 0;
        !           267: 
        !           268:     return( kIOReturnSuccess );
        !           269: }
        !           270: 
        !           271: IOReturn IONDRVFramebuffer::setInterruptState( void * interruptRef, 
        !           272:                                                UInt32 state )
        !           273: {
        !           274:     return( kIOReturnUnsupported );
        !           275: }
        !           276: 
        !           277: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           278: 
        !           279: //// VSL calls
        !           280: 
        !           281: OSStatus IONDRVFramebuffer::VSLNewInterruptService(
        !           282:                                         void * entryID,
        !           283:                                         IOSelect serviceType,
        !           284:                                         _VSLService ** vslService )
        !           285: {
        !           286:     IORegistryEntry *  regEntry;
        !           287:     IONDRVFramebuffer *        fb;
        !           288:     _VSLService *      service;
        !           289:     IOReturn           err = kIOReturnSuccess;
        !           290: 
        !           291:     REG_ENTRY_TO_OBJ( (const RegEntryID *) entryID, regEntry)
        !           292: 
        !           293:     fb = OSDynamicCast( IONDRVFramebuffer,
        !           294:                regEntry->getChildEntry( gIOServicePlane ));
        !           295:     assert( fb );
        !           296: 
        !           297:     if( fb) {
        !           298:        service = IONew( _VSLService, 1 );
        !           299: 
        !           300:        if( service) {
        !           301:             service->framebuffer       = fb;
        !           302:             service->type              = serviceType;
        !           303:            service->handler            = 0;
        !           304:             service->next = fb->vslServices;
        !           305:             fb->vslServices = service;
        !           306: 
        !           307:             *vslService = service;
        !           308: 
        !           309:        } else
        !           310:            err = kIOReturnNoMemory;
        !           311: 
        !           312:     } else
        !           313:        err = kIOReturnBadArgument;
        !           314: 
        !           315:     return( err );
        !           316: }
        !           317: 
        !           318: OSStatus IONDRVFramebuffer::VSLDisposeInterruptService(_VSLService * vslService)
        !           319: {
        !           320:     IONDRVFramebuffer *        fb;
        !           321:     _VSLService *      next;
        !           322:     _VSLService *      prev;
        !           323: 
        !           324:     if( vslService) {
        !           325: 
        !           326:        fb = vslService->framebuffer;
        !           327: 
        !           328:         prev = fb->vslServices;
        !           329:        if( prev == vslService)
        !           330:            fb->vslServices = vslService->next;
        !           331:        else {
        !           332:            while( ((next = prev->next) != vslService) && next)
        !           333:                prev = next;
        !           334:            if( next)
        !           335:                prev->next = vslService->next;
        !           336:        }
        !           337: 
        !           338:        IODelete( vslService, _VSLService, 1 );
        !           339:     }
        !           340: 
        !           341:     return( kIOReturnSuccess );
        !           342: }
        !           343: 
        !           344: OSStatus IONDRVFramebuffer::VSLDoInterruptService( _VSLService * vslService )
        !           345: {
        !           346:     IOFBInterruptProc  proc;
        !           347: 
        !           348:     if( vslService) {
        !           349:        if( (proc = vslService->handler))
        !           350:            (*proc) (vslService->target, vslService->ref);
        !           351:     }
        !           352: 
        !           353:     return( kIOReturnSuccess );
        !           354: }
        !           355: 
        !           356: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           357: 
        !           358: struct _VSLCursorRef {
        !           359:     IOFramebuffer *    framebuffer;
        !           360:     void *             cursorImage;
        !           361: };
        !           362: 
        !           363: Boolean IONDRVFramebuffer::VSLPrepareCursorForHardwareCursor(
        !           364:                                         void * cursorRef,
        !           365:                                         IOHardwareCursorDescriptor * hwDesc,
        !           366:                                         IOHardwareCursorInfo * hwCursorInfo )
        !           367: {
        !           368:     _VSLCursorRef *    cursor = (_VSLCursorRef *) cursorRef;
        !           369:     bool               ok;
        !           370: 
        !           371:     if( hwCursorInfo->colorMap)
        !           372:         hwCursorInfo->colorMap += 1;
        !           373:     ok = cursor->framebuffer->convertCursorImage(
        !           374:                cursor->cursorImage, hwDesc, hwCursorInfo );
        !           375:     if( hwCursorInfo->colorMap)
        !           376:         hwCursorInfo->colorMap -= 1;
        !           377: 
        !           378:     return( ok );
        !           379: }
        !           380: 
        !           381: IOReturn IONDRVFramebuffer::setCursorImage( void * cursorImage )
        !           382: {
        !           383:     _VSLCursorRef              cursorRef;
        !           384:     VDSetHardwareCursorRec     setCursor;
        !           385:     IOReturn                   err;
        !           386: 
        !           387:     cursorRef.framebuffer = this;
        !           388:     cursorRef.cursorImage = cursorImage;
        !           389: 
        !           390:     setCursor.csCursorRef = (void *) &cursorRef;
        !           391:     setCursor.csReserved1 = 0;
        !           392:     setCursor.csReserved2 = 0;
        !           393: 
        !           394:     err = doControl( cscSetHardwareCursor, &setCursor );
        !           395: 
        !           396:     return( err );
        !           397: }
        !           398: 
        !           399: IOReturn IONDRVFramebuffer::setCursorState( SInt32 x, SInt32 y, bool visible )
        !           400: {
        !           401:     VDDrawHardwareCursorRec    drawCursor;
        !           402:     IOReturn                   err;
        !           403: 
        !           404:     if( 0 == OSIncrementAtomic( &ndrvEnter))
        !           405:     {
        !           406: 
        !           407:         drawCursor.csCursorX   = x;
        !           408:         drawCursor.csCursorY   = y;
        !           409:         drawCursor.csCursorVisible     = visible;
        !           410:         drawCursor.csReserved1         = 0;
        !           411:         drawCursor.csReserved2         = 0;
        !           412: 
        !           413:         err = doControl( cscDrawHardwareCursor, &drawCursor );
        !           414: 
        !           415:     } else
        !           416:        err = kIOReturnBusy;
        !           417: 
        !           418:     OSDecrementAtomic( &ndrvEnter );
        !           419: 
        !           420:     return( err );
        !           421: }
        !           422: 
        !           423: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !           424: 
        !           425: //============
        !           426: //= Internal =
        !           427: //============
        !           428: 
        !           429: IOReturn IONDRVFramebuffer::doControl( UInt32 code, void * params )
        !           430: {
        !           431:     IOReturn   err;
        !           432:     CntrlParam pb;
        !           433: 
        !           434:     if( ndrvState == 0)
        !           435:        return( kIOReturnNotOpen);
        !           436: 
        !           437:     pb.qLink = 0;
        !           438:     pb.csCode = code;
        !           439:     pb.csParams = params;
        !           440: 
        !           441:     OSIncrementAtomic( &ndrvEnter );
        !           442:     err = ndrv->doDriverIO( /*ID*/ (UInt32) &pb, &pb,
        !           443:                             kControlCommand, kImmediateIOCommandKind );
        !           444:     OSDecrementAtomic( &ndrvEnter );
        !           445: 
        !           446:     return( err);
        !           447: }
        !           448: 
        !           449: IOReturn IONDRVFramebuffer::doStatus( UInt32 code, void * params )
        !           450: {
        !           451:     IOReturn   err;
        !           452:     CntrlParam pb;
        !           453: 
        !           454:     if( ndrvState == 0)
        !           455:        return( kIOReturnNotOpen);
        !           456: 
        !           457:     pb.qLink = 0;
        !           458:     pb.csCode = code;
        !           459:     pb.csParams = params;
        !           460: 
        !           461:     OSIncrementAtomic( &ndrvEnter );
        !           462:     err = ndrv->doDriverIO( /*ID*/ (UInt32) &pb, &pb,
        !           463:                             kStatusCommand, kImmediateIOCommandKind );
        !           464:     OSDecrementAtomic( &ndrvEnter );
        !           465: 
        !           466:     return( err);
        !           467: }
        !           468: 
        !           469: 
        !           470: IOReturn IONDRVFramebuffer::checkDriver( void )
        !           471: {
        !           472:     OSStatus                   err = noErr;
        !           473:     struct DriverInitInfo      initInfo;
        !           474:     CntrlParam                 pb;
        !           475:     VDClutBehavior             clutSetting;
        !           476:     VDGammaRecord              gammaRec;
        !           477:     VDSwitchInfoRec            switchInfo;
        !           478:     IOTimingInformation        info;
        !           479:     VDPageInfo                 pageInfo;
        !           480: 
        !           481:     if( ndrvState == 0) {
        !           482:        do {
        !           483:            initInfo.refNum = 0xffcd;                   // ...sure.
        !           484:            MAKE_REG_ENTRY(initInfo.deviceEntry, nub )
        !           485:     
        !           486:            err = ndrv->doDriverIO( 0, &initInfo,
        !           487:                                kInitializeCommand, kImmediateIOCommandKind );
        !           488:            if( err) continue;
        !           489: 
        !           490:            err = ndrv->doDriverIO( 0, &pb,
        !           491:                                kOpenCommand, kImmediateIOCommandKind );
        !           492: 
        !           493:        } while( false);
        !           494: 
        !           495:        if( err)
        !           496:            return( err);
        !           497: 
        !           498:         // allow calls to ndrv
        !           499:         ndrvState = 1;
        !           500: 
        !           501:         if( (noErr == doStatus( cscGetCurMode, &switchInfo ))
        !           502:             && (noErr == getTimingInfoForDisplayMode( switchInfo.csData, &info))
        !           503:             && (timingApple_0x0_0hz_Offline == info.appleTimingID)) {
        !           504: 
        !           505:             IOLog("%s: display offline\n", getName());
        !           506:             err = kIOReturnOffline;
        !           507:             return( err);
        !           508:         } else
        !           509:             ndrvState = 2;
        !           510: 
        !           511:         // duplicate QD InitGDevice
        !           512:         pageInfo.csMode = switchInfo.csMode;
        !           513:         pageInfo.csData = 0;
        !           514:         pageInfo.csPage = 0;
        !           515:         doControl( cscGrayPage, &pageInfo);
        !           516: 
        !           517:         clutSetting = kSetClutAtSetEntries;
        !           518:         lastClutSetting = clutSetting;
        !           519:         doControl( cscSetClutBehavior, &clutSetting);
        !           520: 
        !           521: #if 1
        !           522:        // bogus for ROM control
        !           523:        do {
        !           524: 
        !           525:            VDGetGammaListRec   scan;
        !           526:            VDRetrieveGammaRec  get;
        !           527:            GammaTbl *          table;
        !           528:            char                name[ 64 ];
        !           529: 
        !           530:            scan.csPreviousGammaTableID = kGammaTableIDFindFirst;
        !           531:            scan.csGammaTableName = name;
        !           532:            err = doStatus( cscGetGammaInfoList, &scan);
        !           533:            if( err || (scan.csGammaTableID == kGammaTableIDNoMoreTables))
        !           534:                continue;
        !           535: 
        !           536:            table = (GammaTbl *)IOMalloc( scan.csGammaTableSize);
        !           537:            if( 0 == table)
        !           538:                continue;
        !           539:            get.csGammaTableID = scan.csGammaTableID;
        !           540:            get.csGammaTablePtr = table;
        !           541:            
        !           542:            err = doStatus( cscRetrieveGammaTable, &get );
        !           543:            if( noErr == err) {
        !           544:                kprintf("Setting gamma %s\n", scan.csGammaTableName);
        !           545:                gammaRec.csGTable = (Ptr) table;
        !           546:                doControl( cscSetGamma, &gammaRec );
        !           547:            }
        !           548: 
        !           549:            IOFree( table, scan.csGammaTableSize);
        !           550: 
        !           551:        } while( false);
        !           552: #endif
        !           553:     }
        !           554:     return( noErr);
        !           555: }
        !           556: 
        !           557: 
        !           558: UInt32 IONDRVFramebuffer::iterateAllModes( IODisplayModeID * displayModeIDs )
        !           559: {
        !           560:     VDResolutionInfoRec        info;
        !           561:     UInt32             num = 0;
        !           562: 
        !           563:     info.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
        !           564: 
        !           565:     while( 
        !           566:           (noErr == doStatus( cscGetNextResolution, &info))
        !           567:        && ((SInt32) info.csDisplayModeID > 0) ) {
        !           568: 
        !           569:            if( displayModeIDs)
        !           570:                displayModeIDs[ num ] = info.csDisplayModeID;
        !           571: 
        !           572:            info.csPreviousDisplayModeID = info.csDisplayModeID;
        !           573:            num++;
        !           574:     }
        !           575:     return( num);
        !           576: }
        !           577: 
        !           578: 
        !           579: IOReturn IONDRVFramebuffer::getResInfoForMode( IODisplayModeID modeID,
        !           580:                                VDResolutionInfoRec ** theInfo )
        !           581: {
        !           582:     // unfortunately, there is no "kDisplayModeIDFindSpecific"
        !           583: 
        !           584:     if( (SInt32) modeID <= 0)
        !           585:         return( kIOReturnUnsupportedMode);
        !           586: 
        !           587:     *theInfo = &cachedVDResolution;
        !           588: 
        !           589:     if( cachedVDResolution.csDisplayModeID == (UInt32) modeID)
        !           590:        return( noErr);
        !           591: 
        !           592:     // try the next after cached mode
        !           593:     cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID;
        !           594: 
        !           595:     if( (noErr == doStatus( cscGetNextResolution, &cachedVDResolution))
        !           596:     && (cachedVDResolution.csDisplayModeID == (UInt32) modeID) )
        !           597:        return( noErr);
        !           598: 
        !           599:     // full blown iterate
        !           600:     cachedVDResolution.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
        !           601: 
        !           602:     while(
        !           603:        (noErr == doStatus( cscGetNextResolution, &cachedVDResolution))
        !           604:     && (cachedVDResolution.csDisplayModeID != (UInt32) modeID) 
        !           605:     && ((SInt32) cachedVDResolution.csDisplayModeID > 0)) {
        !           606: 
        !           607:        cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID;
        !           608:     }
        !           609: 
        !           610:     if( cachedVDResolution.csDisplayModeID == (UInt32) modeID)
        !           611:        return( noErr);
        !           612: 
        !           613:     cachedVDResolution.csDisplayModeID = 0xffffffff;
        !           614:     return( kIOReturnUnsupportedMode);
        !           615: }
        !           616: 
        !           617: void IONDRVFramebuffer::getCurrentConfiguration( void )
        !           618: {
        !           619:     IOReturn           err;
        !           620:     VDSwitchInfoRec    switchInfo;
        !           621:     VDGrayRecord       grayRec;
        !           622: 
        !           623:     grayRec.csMode = 0;                        // turn off luminance map
        !           624:     err = doControl( cscSetGray, &grayRec );
        !           625:     // driver refused => mono display
        !           626:     grayMode = ((noErr == err) && (0 != grayRec.csMode));
        !           627: 
        !           628:     err = doStatus( cscGetCurMode, &switchInfo );
        !           629:     if( err == noErr) {
        !           630:         currentDisplayMode     = switchInfo.csData;
        !           631:         currentDepth           = switchInfo.csMode - kDepthMode1;
        !           632:         currentPage            = switchInfo.csPage;
        !           633:        if( 0 == (physicalFramebuffer = pmap_extract( kernel_pmap,
        !           634:                ((vm_address_t) switchInfo.csBaseAddr) )))
        !           635:            physicalFramebuffer = (UInt32) switchInfo.csBaseAddr;
        !           636:     } else
        !           637:        IOLog("%s: cscGetCurMode failed\n", nub->getName());
        !           638: }
        !           639: 
        !           640: IODeviceMemory * IONDRVFramebuffer::makeSubRange( 
        !           641:        IOPhysicalAddress       start,
        !           642:        IOPhysicalLength        length ) 
        !           643: {
        !           644:     IODeviceMemory *   mem = 0;
        !           645:     UInt32             numMaps, i;
        !           646:     IOService *                device;
        !           647: 
        !           648:     device = nub;
        !           649:     numMaps = device->getDeviceMemoryCount();
        !           650: 
        !           651:     for( i = 0; (!mem) && (i < numMaps); i++) {
        !           652:        mem = device->getDeviceMemoryWithIndex(i);
        !           653:        if( !mem)
        !           654:            continue;
        !           655:        mem = IODeviceMemory::withSubRange( mem,
        !           656:                        start - mem->getPhysicalAddress(), length );
        !           657:     }
        !           658:     if( !mem)
        !           659:        mem = IODeviceMemory::withRange( start, length );
        !           660: 
        !           661:     return( mem );
        !           662: }
        !           663: 
        !           664: IODeviceMemory * IONDRVFramebuffer::getApertureRange( IOPixelAperture aper )
        !           665: {
        !           666:     IOReturn                   err;
        !           667:     IOPixelInformation         info;
        !           668:     IOByteCount                        bytes;
        !           669: 
        !           670:     err = getPixelInformation( currentDisplayMode, currentDepth, aper,
        !           671:                                 &info );
        !           672:     if( err)
        !           673:        return( 0 );
        !           674: 
        !           675:     bytes = (info.bytesPerRow * info.activeHeight) + 128;
        !           676: 
        !           677:     return( makeSubRange( physicalFramebuffer, bytes ));
        !           678: }
        !           679: 
        !           680: IODeviceMemory * IONDRVFramebuffer::findVRAM( void )
        !           681: {
        !           682:     VDVideoParametersInfoRec   pixelParams;
        !           683:     VPBlock                    pixelInfo;
        !           684:     VDResolutionInfoRec                vdRes;
        !           685:     UInt32                     size;
        !           686:     IOPhysicalAddress          vramBase;
        !           687:     IOByteCount                        vramLength;
        !           688:     IOReturn                   err;
        !           689: 
        !           690:     vramLength = 0;
        !           691:     vdRes.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution;
        !           692:     while(
        !           693:         (noErr == doStatus( cscGetNextResolution, &vdRes))
        !           694:     && ((SInt32) vdRes.csDisplayModeID > 0) )
        !           695:     {
        !           696:         pixelParams.csDisplayModeID = vdRes.csDisplayModeID;
        !           697:         pixelParams.csDepthMode = vdRes.csMaxDepthMode;
        !           698:         pixelParams.csVPBlockPtr = &pixelInfo;
        !           699:         err = doStatus( cscGetVideoParameters, &pixelParams);
        !           700:         if( err)
        !           701:             continue;
        !           702: 
        !           703:         // Control hangs its framebuffer off the end of the aperture to support
        !           704:         // 832 x 624 @ 32bpp. The commented out version will correctly calculate
        !           705:         // the vram length, but DPS needs the full extent to be mapped, so we'll
        !           706:         // end up mapping an extra page that will address vram through the
        !           707:         // little endian aperture. No other drivers like this known.
        !           708: #if 1
        !           709:         size = 0x40 + pixelInfo.vpBounds.bottom *
        !           710:                        (pixelInfo.vpRowBytes & 0x7fff);
        !           711: #else
        !           712:         size = ( (pixelInfo.vpBounds.right * pixelInfo.vpPixelSize) / 8)       // last line
        !           713:                 + (pixelInfo.vpBounds.bottom - 1) *
        !           714:                (pixelInfo.vpRowBytes & 0x7fff);
        !           715: #endif
        !           716:         if( size > vramLength)
        !           717:             vramLength = size;
        !           718: 
        !           719:         vdRes.csPreviousDisplayModeID = vdRes.csDisplayModeID;
        !           720:     }
        !           721: 
        !           722:     vramBase = physicalFramebuffer;
        !           723:     vramLength = (vramLength + (vramBase & 0xffff) + 0xffff) & 0xffff0000;
        !           724:     vramBase &= 0xffff0000;
        !           725: 
        !           726:     return( makeSubRange( vramBase, vramLength ));
        !           727: }
        !           728: 
        !           729: //============
        !           730: //= External =
        !           731: //============
        !           732: 
        !           733: const char * IONDRVFramebuffer::getPixelFormats( void )
        !           734: {
        !           735:     static const char * ndrvPixelFormats =
        !           736:         IO1BitIndexedPixels "\0"
        !           737:         IO2BitIndexedPixels "\0"
        !           738:         IO4BitIndexedPixels "\0"
        !           739:         IO8BitIndexedPixels "\0"
        !           740:         IO16BitDirectPixels "\0"
        !           741:         IO32BitDirectPixels "\0"
        !           742:         "\0";
        !           743: 
        !           744:     return( ndrvPixelFormats);
        !           745: }
        !           746: 
        !           747: IOItemCount IONDRVFramebuffer::getDisplayModeCount( void )
        !           748: {
        !           749:     return( iterateAllModes( 0 ));
        !           750: }
        !           751: 
        !           752: IOReturn IONDRVFramebuffer::getDisplayModes( IODisplayModeID * allDisplayModes )
        !           753: {
        !           754:     iterateAllModes( allDisplayModes );
        !           755:     return( kIOReturnSuccess );
        !           756: }
        !           757: 
        !           758: IOReturn IONDRVFramebuffer::getInformationForDisplayMode(
        !           759:                IODisplayModeID displayMode, IODisplayModeInformation * info )
        !           760: {
        !           761:     IOReturn                   err;
        !           762:     VDResolutionInfoRec        *       resInfo;
        !           763: 
        !           764:     bzero( info, sizeof( *info));
        !           765:     do {
        !           766:        err = getResInfoForMode( displayMode, &resInfo );
        !           767:        if( err)
        !           768:            continue;
        !           769:        info->maxDepthIndex     = resInfo->csMaxDepthMode - kDepthMode1;
        !           770:        info->nominalWidth      = resInfo->csHorizontalPixels;
        !           771:        info->nominalHeight     = resInfo->csVerticalLines;
        !           772:        info->refreshRate       = resInfo->csRefreshRate;
        !           773:        return( noErr);
        !           774:     } while( false);
        !           775: 
        !           776:     return( kIOReturnUnsupportedMode);
        !           777: }
        !           778: 
        !           779: 
        !           780: UInt64 IONDRVFramebuffer::getPixelFormatsForDisplayMode(
        !           781:                IODisplayModeID /* displayMode */, IOIndex depthIndex )
        !           782: {
        !           783:     return( 1 << (depthIndex + startAt8));
        !           784: }
        !           785: 
        !           786: IOReturn IONDRVFramebuffer::getPixelInformation(
        !           787:        IODisplayModeID displayMode, IOIndex depth,
        !           788:        IOPixelAperture aperture, IOPixelInformation * info )
        !           789: {
        !           790:     SInt32                     err;
        !           791:     VDVideoParametersInfoRec   pixelParams;
        !           792:     VPBlock                    pixelInfo;
        !           793:     const char *               formats;
        !           794:     UInt32                     mask;
        !           795:     int                                index;
        !           796: 
        !           797:     bzero( info, sizeof( *info));
        !           798: 
        !           799:     if( aperture)
        !           800:         return( kIOReturnUnsupportedMode);
        !           801: 
        !           802:     do {
        !           803:        pixelParams.csDisplayModeID = displayMode;
        !           804:        pixelParams.csDepthMode = depth + kDepthMode1;
        !           805:        pixelParams.csVPBlockPtr = &pixelInfo;
        !           806:        err = doStatus( cscGetVideoParameters, &pixelParams );
        !           807:        if( err)
        !           808:            continue;
        !           809: 
        !           810:        //info->flags = kFramebufferSupportsCopybackCache;    
        !           811: 
        !           812:        info->activeWidth       = pixelInfo.vpBounds.right;
        !           813:        info->activeHeight      = pixelInfo.vpBounds.bottom;
        !           814:        info->bytesPerRow       = pixelInfo.vpRowBytes & 0x7fff;
        !           815:        info->bytesPerPlane     = pixelInfo.vpPlaneBytes;
        !           816:        info->bitsPerPixel      = pixelInfo.vpPixelSize;
        !           817: 
        !           818:         formats = getPixelFormats();
        !           819:         mask = getPixelFormatsForDisplayMode( displayMode, depth );
        !           820: 
        !           821:         for( index = 0; index < 32; index++) {
        !           822:             if( (mask & (1 << index)) && ((aperture--) == 0)) {
        !           823:                 strcpy( info->pixelFormat, formats);
        !           824:                 break;
        !           825:             }
        !           826:             formats += strlen( formats) + 1;
        !           827:         }
        !           828: 
        !           829:         if( 0 == strcmp("PPPPPPPP", info->pixelFormat)) {
        !           830:             info->pixelType = kIOCLUTPixels;
        !           831:             info->componentMasks[0] = 0xff;
        !           832:             info->bitsPerPixel = 8;
        !           833:             info->componentCount = 1;
        !           834:             info->bitsPerComponent = 8;
        !           835: 
        !           836:         } else if( 0 == strcmp("-RRRRRGGGGGBBBBB", info->pixelFormat)) {
        !           837:             info->pixelType = kIORGBDirectPixels;
        !           838:             info->componentMasks[0] = 0x7c00;
        !           839:             info->componentMasks[1] = 0x03e0;
        !           840:             info->componentMasks[2] = 0x001f;
        !           841:             info->bitsPerPixel = 16;
        !           842:             info->componentCount = 3;
        !           843:             info->bitsPerComponent = 5;
        !           844: 
        !           845:         } else if( 0 == strcmp("--------RRRRRRRRGGGGGGGGBBBBBBBB",
        !           846:                                         info->pixelFormat)) {
        !           847:             info->pixelType = kIORGBDirectPixels;
        !           848:             info->componentMasks[0] = 0x00ff0000;
        !           849:             info->componentMasks[1] = 0x0000ff00;
        !           850:             info->componentMasks[2] = 0x000000ff;
        !           851:             info->bitsPerPixel = 32;
        !           852:             info->componentCount = 3;
        !           853:             info->bitsPerComponent = 8;
        !           854:         }
        !           855: 
        !           856:     } while( false);
        !           857: 
        !           858:     return( err);
        !           859: }
        !           860: 
        !           861: IOReturn IONDRVFramebuffer::getTimingInfoForDisplayMode(
        !           862:                IODisplayModeID displayMode, IOTimingInformation * info )
        !           863: {
        !           864:     VDTimingInfoRec            timingInfo;
        !           865:     OSStatus                   err;
        !           866: 
        !           867:     timingInfo.csTimingMode = displayMode;
        !           868:     // in case the driver doesn't do it:
        !           869:     timingInfo.csTimingFormat = kDeclROMtables;
        !           870:     err = doStatus( cscGetModeTiming, &timingInfo);
        !           871:     if( err == noErr) {
        !           872:        if( timingInfo.csTimingFormat == kDeclROMtables)
        !           873:            info->appleTimingID = timingInfo.csTimingData;
        !           874:        else
        !           875:            info->appleTimingID = timingInvalid;
        !           876: 
        !           877:        return( kIOReturnSuccess);
        !           878:     }
        !           879: 
        !           880:     return( kIOReturnUnsupportedMode);
        !           881: }
        !           882: 
        !           883: IOReturn IONDRVFramebuffer::getCurrentDisplayMode( 
        !           884:                                IODisplayModeID * displayMode, IOIndex * depth )
        !           885: {
        !           886:     if( displayMode)
        !           887:        *displayMode = currentDisplayMode;
        !           888:     if( depth)
        !           889:        *depth = currentDepth;
        !           890: 
        !           891:     return( kIOReturnSuccess);
        !           892: }
        !           893: 
        !           894: IOReturn IONDRVFramebuffer::setDisplayMode( IODisplayModeID displayMode, IOIndex depth )
        !           895: {
        !           896:     SInt32             err;
        !           897:     VDSwitchInfoRec    switchInfo;
        !           898:     VDPageInfo         pageInfo;
        !           899: 
        !           900:     switchInfo.csData = displayMode;
        !           901:     switchInfo.csMode = depth + kDepthMode1;
        !           902:     switchInfo.csPage = 0;
        !           903:     err = doControl( cscSwitchMode, &switchInfo);
        !           904:     if(err)
        !           905:        IOLog("%s: cscSwitchMode:%d\n", nub->getName(), (int)err);
        !           906: 
        !           907:     // duplicate QD InitGDevice
        !           908:     pageInfo.csMode = switchInfo.csMode;
        !           909:     pageInfo.csData = 0;
        !           910:     pageInfo.csPage = 0;
        !           911:     doControl( cscSetMode, &pageInfo);
        !           912:     doControl( cscGrayPage, &pageInfo);
        !           913: 
        !           914:     getCurrentConfiguration();
        !           915: 
        !           916:     return( err);
        !           917: }
        !           918: 
        !           919: IOReturn IONDRVFramebuffer::setStartupDisplayMode(
        !           920:                        IODisplayModeID displayMode, IOIndex depth )
        !           921: {
        !           922:     SInt32             err;
        !           923:     VDSwitchInfoRec    switchInfo;
        !           924: 
        !           925:     switchInfo.csData = displayMode;
        !           926:     switchInfo.csMode = depth + kDepthMode1;
        !           927:     err = doControl( cscSavePreferredConfiguration, &switchInfo);
        !           928:     return( err);
        !           929: }
        !           930: 
        !           931: IOReturn IONDRVFramebuffer::getStartupDisplayMode(
        !           932:                                IODisplayModeID * displayMode, IOIndex * depth )
        !           933: {
        !           934:     SInt32             err;
        !           935:     VDSwitchInfoRec    switchInfo;
        !           936: 
        !           937:     err = doStatus( cscGetPreferredConfiguration, &switchInfo);
        !           938:     if( err == noErr) {
        !           939:        *displayMode    = switchInfo.csData;
        !           940:        *depth          = switchInfo.csMode - kDepthMode1;
        !           941:     }
        !           942:     return( err);
        !           943: }
        !           944: 
        !           945: IOReturn IONDRVFramebuffer::setApertureEnable( IOPixelAperture /* aperture */,
        !           946:                                                IOOptionBits /* enable */ )
        !           947: {
        !           948:     return( kIOReturnSuccess);
        !           949: }
        !           950: 
        !           951: IOReturn IONDRVFramebuffer::setCLUTWithEntries(
        !           952:                        IOColorEntry * colors, UInt32 index, UInt32 numEntries,
        !           953:                        IOOptionBits options )
        !           954: {
        !           955:     IOReturn           err;
        !           956:     UInt32             code;
        !           957:     VDSetEntryRecord   setEntryRec;
        !           958:     VDClutBehavior     clutSetting;
        !           959:     VDGrayRecord       grayRec;
        !           960: 
        !           961:     if( options & kSetCLUTWithLuminance)
        !           962:         grayRec.csMode = 1;            // turn on luminance map
        !           963:     else
        !           964:         grayRec.csMode = 0;            // turn off luminance map
        !           965: 
        !           966:     if( grayRec.csMode != lastGrayMode) {
        !           967:        doControl( cscSetGray, &grayRec);
        !           968:        lastGrayMode = grayRec.csMode;
        !           969:     }
        !           970: 
        !           971:     if( options & kSetCLUTImmediately)
        !           972:         clutSetting = kSetClutAtSetEntries;
        !           973:     else
        !           974:         clutSetting = kSetClutAtVBL;
        !           975: 
        !           976:     if( clutSetting != lastClutSetting) {
        !           977:        doControl( cscSetClutBehavior, &clutSetting);
        !           978:        lastClutSetting = clutSetting;
        !           979:     }
        !           980: 
        !           981:     if( options & kSetCLUTByValue)
        !           982:         setEntryRec.csStart = -1;
        !           983:     else
        !           984:         setEntryRec.csStart = index;
        !           985: 
        !           986:     setEntryRec.csTable = (ColorSpec *) colors;
        !           987:     setEntryRec.csCount = numEntries - 1;
        !           988:     if( directMode)
        !           989:         code = cscDirectSetEntries;
        !           990:     else
        !           991:         code = cscSetEntries;
        !           992:     err = doControl( code, &setEntryRec);
        !           993: 
        !           994:     return( err);
        !           995: }
        !           996: 
        !           997: IOReturn IONDRVFramebuffer::setGammaTable( UInt32 channelCount, UInt32 dataCount,
        !           998:                                             UInt32 dataWidth, void * data )
        !           999: {
        !          1000:     IOReturn           err;
        !          1001:     VDGammaRecord      gammaRec;
        !          1002:     struct GammaTbl {
        !          1003:         short gVersion;                /*gamma version number*/
        !          1004:         short gType;           /*gamma data type*/
        !          1005:         short gFormulaSize;    /*Formula data size*/
        !          1006:         short gChanCnt;                /*number of channels of data*/
        !          1007:         short gDataCnt;                /*number of values/channel*/
        !          1008:         short gDataWidth;      /*bits/corrected value */
        !          1009:                                /* (data packed to next larger byte size)*/
        !          1010:         UInt8 gFormulaData[0]; /*data for formulas followed by gamma values*/
        !          1011:     };
        !          1012:     GammaTbl *         table = NULL;
        !          1013:     IOByteCount        dataLen = 0;
        !          1014: 
        !          1015:     if( data) {
        !          1016:         dataLen = (dataWidth + 7) / 8;
        !          1017:         dataLen *= dataCount * channelCount;
        !          1018:         table = (GammaTbl *) IOMalloc( dataLen + sizeof( struct GammaTbl));
        !          1019:         if( NULL == table)
        !          1020:             return( kIOReturnNoMemory);
        !          1021: 
        !          1022:        table->gVersion         = 0;
        !          1023:        table->gType            = 0;
        !          1024:        table->gFormulaSize     = 0;
        !          1025:        table->gChanCnt         = channelCount;
        !          1026:        table-> gDataCnt        = dataCount;
        !          1027:        table->gDataWidth       = dataWidth;
        !          1028:        bcopy( data, table->gFormulaData, dataLen);
        !          1029:     }
        !          1030: 
        !          1031:     gammaRec.csGTable = (Ptr) table;
        !          1032:     err = doControl( cscSetGamma, &gammaRec);
        !          1033:     if( table)
        !          1034:         IOFree( table, dataLen + sizeof( struct GammaTbl));
        !          1035: 
        !          1036:     return( err);
        !          1037: }
        !          1038: 
        !          1039: IOReturn IONDRVFramebuffer::getAttribute( IOSelect attribute, UInt32 * value )
        !          1040: {
        !          1041:     IOReturn                   err = kIOReturnSuccess;
        !          1042:     VDSupportsHardwareCursorRec        hwCrsrSupport;
        !          1043: 
        !          1044:     switch( attribute ) {
        !          1045: 
        !          1046:        case kIOHardwareCursorAttribute:
        !          1047: 
        !          1048:            *value = ((kIOReturnSuccess ==
        !          1049:                        doStatus( cscSupportsHardwareCursor, &hwCrsrSupport))
        !          1050:                     && (hwCrsrSupport.csSupportsHardwareCursor));
        !          1051:            break;
        !          1052: 
        !          1053:        default:
        !          1054:            err = super::getAttribute( attribute, value );
        !          1055:     }
        !          1056: 
        !          1057:     return( err );
        !          1058: }
        !          1059: 
        !          1060: UInt32 IONDRVFramebuffer::getConnectionCount( void )
        !          1061: {
        !          1062:     VDMultiConnectInfoRec      theRecord;
        !          1063: 
        !          1064:     if( doStatus(cscGetMultiConnect,&theRecord) == 0 ) {
        !          1065:         return theRecord.csDisplayCountOrNumber;
        !          1066:     }
        !          1067:     return 1;
        !          1068: }
        !          1069: 
        !          1070: IOReturn IONDRVFramebuffer::setAttributeForConnection( IOIndex connectIndex,
        !          1071:                                          IOSelect attribute, UInt32  info )
        !          1072: {
        !          1073:     IOReturn   ret;
        !          1074:     VDSyncInfoRec      theVDSyncInfoRec;
        !          1075: 
        !          1076:     switch( attribute ) {
        !          1077: 
        !          1078:         case kConnectionSyncEnable:
        !          1079:             theVDSyncInfoRec.csMode = (unsigned char)(info>>8);
        !          1080:             theVDSyncInfoRec.csFlags = (unsigned char)(info & 0xFF);
        !          1081:             doControl(cscSetSync,&theVDSyncInfoRec);
        !          1082:             ret = kIOReturnSuccess;
        !          1083:             break;
        !          1084:         default:
        !          1085:             ret = super::setAttributeForConnection( connectIndex,
        !          1086:                                        attribute, info );
        !          1087:             break;
        !          1088:     }
        !          1089:     return( ret );
        !          1090: }
        !          1091: 
        !          1092:             
        !          1093: IOReturn IONDRVFramebuffer::getAttributeForConnection( IOIndex connectIndex,
        !          1094:                                          IOSelect attribute, UInt32  * value )
        !          1095: {
        !          1096:     IOReturn   ret;
        !          1097:     VDSyncInfoRec      theVDSyncInfoRec;
        !          1098:     
        !          1099:     switch( attribute ) {
        !          1100: 
        !          1101:         case kConnectionSyncFlags:
        !          1102:             // find out current state of sync lines
        !          1103:             theVDSyncInfoRec.csMode = 0x00;
        !          1104:             doStatus(cscGetSync,&theVDSyncInfoRec);
        !          1105:             * value = theVDSyncInfoRec.csMode;
        !          1106:             ret = kIOReturnSuccess;
        !          1107:             break;
        !          1108:         case kConnectionSyncEnable:
        !          1109:             // what are the sync-controlling capabilities of the ndrv?
        !          1110:             theVDSyncInfoRec.csMode = 0xFF;
        !          1111:             doStatus(cscGetSync,&theVDSyncInfoRec);
        !          1112:             * value = (UInt32)theVDSyncInfoRec.csMode;
        !          1113:             ret = kIOReturnSuccess;
        !          1114:             break;
        !          1115:         case kConnectionSupportsHLDDCSense:
        !          1116:         case kConnectionSupportsAppleSense:
        !          1117:             ret = kIOReturnSuccess;
        !          1118:             break;
        !          1119:         default:
        !          1120:             ret = super::getAttributeForConnection( connectIndex,
        !          1121:                                attribute, value );
        !          1122:             break;
        !          1123:     }
        !          1124: 
        !          1125:     return( ret );
        !          1126: }
        !          1127: 
        !          1128: IOReturn IONDRVFramebuffer::getAppleSense( IOIndex  connectIndex,
        !          1129:                                             UInt32 * senseType,
        !          1130:                                             UInt32 * primary,
        !          1131:                                             UInt32 * extended,
        !          1132:                                             UInt32 * displayType )
        !          1133: {
        !          1134:     OSStatus           err;
        !          1135:     VDMultiConnectInfoRec      multiConnect;
        !          1136:     UInt32                     sense, extSense;
        !          1137: 
        !          1138:     if( connectIndex == 0 )
        !          1139:         err = doStatus( cscGetConnection, &multiConnect.csConnectInfo);
        !          1140: 
        !          1141:     else {
        !          1142:         multiConnect.csDisplayCountOrNumber = connectIndex;
        !          1143:         err = doControl( cscSetMultiConnect, &multiConnect);
        !          1144:     }
        !          1145:     if( err)
        !          1146:        return( err);
        !          1147: 
        !          1148:     if( multiConnect.csConnectInfo.csConnectFlags 
        !          1149:       & ((1<<kReportsTagging) | (1<<kTaggingInfoNonStandard))
        !          1150:        != ((1<<kReportsTagging)) )
        !          1151: 
        !          1152:        err = kIOReturnUnsupported;
        !          1153: 
        !          1154:     else {
        !          1155: 
        !          1156:         sense          = multiConnect.csConnectInfo.csConnectTaggedType;
        !          1157:         extSense       = multiConnect.csConnectInfo.csConnectTaggedData;
        !          1158:        // bug fixes for really old ATI driver
        !          1159:         if( sense == 0) {
        !          1160:             if( extSense == 6) {
        !          1161:                 sense                  = kRSCSix;
        !          1162:                 extSense        = kESCSixStandard;
        !          1163:             }
        !          1164:             else
        !          1165:                 if( extSense == 4) {
        !          1166:                 sense          = kRSCFour;
        !          1167:                 extSense        = kESCFourNTSC;
        !          1168:                 }
        !          1169:             }
        !          1170:         if( primary)
        !          1171:             *primary = sense;
        !          1172:         if( extended)
        !          1173:             *extended = extSense;
        !          1174:         if( displayType)
        !          1175:             *displayType = multiConnect.csConnectInfo.csDisplayType;
        !          1176:         if( senseType)
        !          1177:             *senseType = 0;
        !          1178:     }
        !          1179:     return( err);
        !          1180: }
        !          1181: 
        !          1182: IOReturn IONDRVFramebuffer::connectFlags( IOIndex /* connectIndex */,
        !          1183:                              IODisplayModeID displayMode, IOOptionBits * flags )
        !          1184: {
        !          1185:     VDTimingInfoRec            timingInfo;
        !          1186:     OSStatus                   err;
        !          1187: 
        !          1188:     timingInfo.csTimingMode = displayMode;
        !          1189:     // in case the driver doesn't do it:
        !          1190:     timingInfo.csTimingFormat = kDeclROMtables;
        !          1191:     err = doStatus( cscGetModeTiming, &timingInfo);
        !          1192:     *flags = timingInfo.csTimingFlags;
        !          1193:     return( err );
        !          1194: }
        !          1195: 
        !          1196: 
        !          1197: bool IONDRVFramebuffer::hasDDCConnect( IOIndex  connectIndex )
        !          1198: {
        !          1199:     OSStatus           err;
        !          1200:     VDMultiConnectInfoRec      multiConnect;
        !          1201:     enum               {       kNeedFlags = (1<<kReportsDDCConnection)
        !          1202:                                           | (1<<kHasDDCConnection) };
        !          1203:     if( connectIndex == 0 )
        !          1204:         err = doStatus( cscGetConnection, &multiConnect.csConnectInfo);
        !          1205:     else {
        !          1206:         multiConnect.csDisplayCountOrNumber = connectIndex;
        !          1207:         err = doControl( cscSetMultiConnect, &multiConnect);
        !          1208:     }
        !          1209:     if( err)
        !          1210:         return( err);
        !          1211: 
        !          1212:     return( (multiConnect.csConnectInfo.csConnectFlags & kNeedFlags)
        !          1213:                == kNeedFlags );
        !          1214: }
        !          1215: 
        !          1216: IOReturn IONDRVFramebuffer::getDDCBlock( IOIndex /* connectIndex */, 
        !          1217:                                        UInt32 blockNumber,
        !          1218:                                         IOSelect blockType,
        !          1219:                                        IOOptionBits options,
        !          1220:                                         UInt8 * data, IOByteCount * length )
        !          1221: 
        !          1222: {
        !          1223:     OSStatus           err = 0;
        !          1224:     VDDDCBlockRec      ddcRec;
        !          1225:     ByteCount          actualLength = *length;
        !          1226: 
        !          1227:     ddcRec.ddcBlockNumber      = blockNumber;
        !          1228:     ddcRec.ddcBlockType        = blockType;
        !          1229:     ddcRec.ddcFlags            = options;
        !          1230: 
        !          1231:     err = doStatus( cscGetDDCBlock, &ddcRec);
        !          1232: 
        !          1233:     if( err == noErr) {
        !          1234: 
        !          1235:        if( actualLength < kDDCBlockSize)
        !          1236:             actualLength = actualLength;
        !          1237:        else
        !          1238:             actualLength = kDDCBlockSize;
        !          1239:         bcopy( ddcRec.ddcBlockData, data, actualLength);
        !          1240:        *length = actualLength;
        !          1241:     }
        !          1242:     return( err);
        !          1243: }
        !          1244: 
        !          1245: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1246: // initForPM
        !          1247: //
        !          1248: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1249: void IONDRVFramebuffer::initForPM ( void )
        !          1250: {
        !          1251:     // register ourselves with superclass policy-maker
        !          1252:     registerControllingDriver(this,ourPowerStates,number_of_power_states);
        !          1253: }
        !          1254: 
        !          1255: 
        !          1256: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1257: // maxCapabilityForDomainState
        !          1258: //
        !          1259: // This simple device needs only power.  If the power domain is supplying
        !          1260: // power, the frame buffer can be on.  If there is no power it can only be off.
        !          1261: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1262: 
        !          1263: unsigned long  IONDRVFramebuffer::maxCapabilityForDomainState(
        !          1264:                                        IOPMPowerFlags domainState )
        !          1265: {
        !          1266:    if( domainState &  IOPMPowerOn )
        !          1267:        return number_of_power_states-1;
        !          1268:    else
        !          1269:        return 0;
        !          1270: }
        !          1271: 
        !          1272: 
        !          1273: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1274: // initialPowerStateForDomainState
        !          1275: //
        !          1276: // The power domain may be changing state.  If power is on in the new
        !          1277: // state, that will not affect our state at all.  If domain power is off,
        !          1278: // we can attain only our lowest state, which is off.
        !          1279: //
        !          1280: // This implementation is incomplete.  It only works in a system where
        !          1281: // the frame buffer is never turned off.  When we cross that bridge,
        !          1282: // instead of returning 1, it should return 1 if the frame buffer
        !          1283: // is on, or 0 if it is off.
        !          1284: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1285: unsigned long IONDRVFramebuffer::initialPowerStateForDomainState(
        !          1286:                                         IOPMPowerFlags domainState )
        !          1287: {
        !          1288:    if( domainState &  IOPMPowerOn )
        !          1289:        return number_of_power_states-1;
        !          1290:    else
        !          1291:        return 0;
        !          1292: }
        !          1293: 
        !          1294: 
        !          1295: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1296: // powerStateForDomainState
        !          1297: //
        !          1298: // The power domain may be changing state.  If power is on in the new
        !          1299: // state, that will not affect our state at all.  If domain power is off,
        !          1300: // we can attain only our lowest state, which is off.
        !          1301: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1302: unsigned long  IONDRVFramebuffer::powerStateForDomainState(
        !          1303:                                        IOPMPowerFlags domainState )
        !          1304: {
        !          1305:    if( domainState &  IOPMPowerOn )
        !          1306:        return pm_vars->myCurrentState;
        !          1307:    else
        !          1308:        return 0;
        !          1309: }
        !          1310: 
        !          1311: 
        !          1312: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1313: // setPowerState
        !          1314: //
        !          1315: // Called by the superclass to turn the frame buffer on and off.
        !          1316: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1317: IOReturn IONDRVFramebuffer::setPowerState( unsigned long powerStateOrdinal,
        !          1318:                                                IOService* whatDevice )
        !          1319: {
        !          1320:     if ( powerStateOrdinal == 0 ) {
        !          1321:         kprintf("frame buffer would be powered off here\n");
        !          1322:     }
        !          1323:     if ( powerStateOrdinal == 1 ) {
        !          1324:         kprintf("frame buffer would be powered on here\n");
        !          1325:     }
        !          1326:     return IOPMAckImplied;
        !          1327: }
        !          1328: 
        !          1329: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1330: 
        !          1331: // ATI patches.
        !          1332: // Real problem : getStartupMode doesn't.
        !          1333: 
        !          1334: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1335: 
        !          1336: #undef super
        !          1337: #define super IONDRVFramebuffer
        !          1338: 
        !          1339: OSDefineMetaClassAndStructors(IOATINDRV, IONDRVFramebuffer)
        !          1340: OSDefineMetaClassAndStructors(IOATI128NDRV, IOATINDRV)
        !          1341: 
        !          1342: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
        !          1343: 
        !          1344: IOReturn IOATINDRV::getStartupDisplayMode(
        !          1345:                                IODisplayModeID * displayMode, IOIndex * depth )
        !          1346: {
        !          1347:     UInt16 *           nvram;
        !          1348:     OSData *           prop;
        !          1349: 
        !          1350:     prop = OSDynamicCast( OSData, nub->getProperty("Sime"));
        !          1351:     if( prop) {
        !          1352:        nvram = (UInt16 *) prop->getBytesNoCopy();
        !          1353:        *displayMode = nvram[ 0 ];      // 1 is physDisplayMode
        !          1354:        *depth = nvram[ 2 ] - kDepthMode1;
        !          1355:         return( kIOReturnSuccess);
        !          1356:     } else
        !          1357:         return(super::getStartupDisplayMode( displayMode, depth));
        !          1358: }
        !          1359: 
        !          1360: IODeviceMemory * IOATINDRV::findVRAM( void )
        !          1361: {
        !          1362:     OSData *           prop;
        !          1363:     IOPhysicalAddress  vramBase;
        !          1364:     IOByteCount                vramLength;
        !          1365: 
        !          1366:     prop = OSDynamicCast( OSData, nub->getProperty("APPL,VRAMSize"));
        !          1367:     if( !prop)
        !          1368:        prop = OSDynamicCast( OSData, nub->getProperty("ATY,memsize"));
        !          1369:     if( !prop)
        !          1370:        return( super::findVRAM());
        !          1371: 
        !          1372:     vramBase = physicalFramebuffer;
        !          1373:     vramLength = *((IOByteCount *)prop->getBytesNoCopy());
        !          1374:     if( !vramLength)
        !          1375:         return( super::findVRAM());
        !          1376:     vramLength = (vramLength + (vramBase & 0xffff)) & 0xffff0000;
        !          1377:     vramBase &= 0xffff0000;
        !          1378: 
        !          1379:     return( makeSubRange( vramBase, vramLength ));
        !          1380: }
        !          1381: 
        !          1382: static int g128ExtraCurs = 8;
        !          1383: static int g128DeltaCurs = 0x25c0;
        !          1384: 
        !          1385: void IOATI128NDRV::flushCursor( void )
        !          1386: {
        !          1387:     volatile UInt32 *  fb;
        !          1388:     UInt32             x;
        !          1389:     int                        i;
        !          1390: 
        !          1391:     fb = (volatile UInt32 *) frameBuffer;
        !          1392:     for( i = 0; i < g128ExtraCurs; i++) {
        !          1393:        x += *(fb++);
        !          1394:        fb += g128DeltaCurs;
        !          1395:     }
        !          1396: }
        !          1397: 
        !          1398: 
        !          1399:     

unix.superglobalmegacorp.com

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