|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* ! 25: * Copyright (c) 1997 Apple Computer, Inc. ! 26: * ! 27: * ! 28: * HISTORY ! 29: * ! 30: * Simon Douglas 22 Oct 97 ! 31: * - first checked in. ! 32: */ ! 33: ! 34: ! 35: #define KERNOBJC 1 // remove ! 36: #define KERNEL_PRIVATE 1 ! 37: #define DRIVER_PRIVATE 1 ! 38: ! 39: #import <driverkit/generalFuncs.h> ! 40: #import <driverkit/IODisplay.h> ! 41: #import <driverkit/IODisplayPrivate.h> ! 42: #import <driverkit/IOFrameBufferShared.h> ! 43: #import <bsd/dev/kmreg_com.h> ! 44: #import <bsd/dev/ppc/kmDevice.h> ! 45: ! 46: #import <mach/vm_param.h> /* for round_page() */ ! 47: #import <machdep/ppc/proc_reg.h> ! 48: #import <string.h> ! 49: ! 50: #import <driverkit/ppc/IOFramebuffer.h> ! 51: #import "IONDRVFramebuffer.h" ! 52: ! 53: extern IODisplayInfo bootDisplayInfo; ! 54: ! 55: @implementation IONDRVFramebuffer ! 56: ! 57: //======================================================================= ! 58: ! 59: - (IOReturn)doControl:(UInt32)code params:(void *)params ! 60: { ! 61: IOReturn err; ! 62: CntrlParam pb; ! 63: ! 64: pb.qLink = 0; ! 65: pb.csCode = code; ! 66: pb.csParams = params; ! 67: ! 68: err = NDRVDoDriverIO( doDriverIO, /*ID*/ (UInt32) &pb, &pb, ! 69: kControlCommand, kImmediateIOCommandKind ); ! 70: ! 71: return( err); ! 72: } ! 73: ! 74: - (IOReturn)doStatus:(UInt32)code params:(void *)params ! 75: { ! 76: IOReturn err; ! 77: CntrlParam pb; ! 78: ! 79: pb.qLink = 0; ! 80: pb.csCode = code; ! 81: pb.csParams = params; ! 82: ! 83: err = NDRVDoDriverIO( doDriverIO, /*ID*/ (UInt32) &pb, &pb, ! 84: kStatusCommand, kImmediateIOCommandKind ); ! 85: ! 86: return( err); ! 87: } ! 88: ! 89: //======================================================================= ! 90: ! 91: + (BOOL)probe:device ! 92: { ! 93: id inst; ! 94: Class newClass = self; ! 95: char * name; ! 96: ! 97: if( NDRVForDevice( device)) { ! 98: name = [device nodeName]; ! 99: if( 0 == strncmp("ATY,", name, strlen("ATY,"))) ! 100: newClass = [IOATINDRV class]; ! 101: else if( 0 == strncmp("IMS,tt3d", name, strlen("IMS,tt3d"))) ! 102: newClass = [IOIX3DNDRV class]; ! 103: } else ! 104: newClass = [IOOFFramebuffer class]; ! 105: ! 106: // Create an instance and initialize ! 107: inst = [[newClass alloc] initFromDeviceDescription:device]; ! 108: if (inst == nil) ! 109: return NO; ! 110: ! 111: [inst setDeviceKind:"Linear Framebuffer"]; ! 112: ! 113: [inst registerDevice]; ! 114: ! 115: return YES; ! 116: } ! 117: ! 118: - initFromDeviceDescription:(IOPCIDevice *) deviceDescription ! 119: { ! 120: id me = nil; ! 121: kern_return_t err = 0; ! 122: UInt32 i, propSize; ! 123: UInt32 numMaps = 8; ! 124: IOApertureInfo maps[ numMaps ]; // FIX ! 125: IOLogicalAddress aaplAddress[ 8 ]; // FIX ! 126: IOApertureInfo * map; ! 127: IOPropertyTable * propTable; ! 128: void * prop; ! 129: char * logname; ! 130: InterruptSetMember intsProperty[ 3 ]; ! 131: ! 132: do { ! 133: ioDevice = deviceDescription; ! 134: logname = [ioDevice nodeName]; ! 135: propTable = [ioDevice propertyTable]; ! 136: ! 137: prop = &ndrvInst; ! 138: propSize = sizeof( NDRVInstance); ! 139: err = [propTable getProperty:"AAPL,ndrvInst" flags:0 value:&prop length:&propSize]; ! 140: if( err) ! 141: continue; ! 142: err = NDRVGetSymbol( ndrvInst, "DoDriverIO", &doDriverIO ); ! 143: if( err) ! 144: continue; ! 145: err = NDRVGetSymbol( ndrvInst, "TheDriverDescription", (void **)&theDriverDesc ); ! 146: if( err) ! 147: continue; ! 148: ! 149: transferTable = IOMalloc(sizeof( ColorSpec) * 256); // Initialize transfer table variables. ! 150: brightnessLevel = EV_SCREEN_MAX_BRIGHTNESS; ! 151: scaledTable = 0; ! 152: cachedModeIndex = 0x7fffffff; ! 153: ! 154: numMaps = 8; ! 155: err = [ioDevice getApertures:maps items:&numMaps]; ! 156: if( err) ! 157: continue; ! 158: ! 159: for( i = 0, map = maps; i < numMaps; i++, map++) { ! 160: ! 161: if( (((UInt32)bootDisplayInfo.frameBuffer) >= ((UInt32)map->physical)) ! 162: && (((UInt32)bootDisplayInfo.frameBuffer) < (map->length + (UInt32)map->physical)) ) ! 163: consoleDevice = YES; ! 164: ! 165: // this means any graphics card grabs a BAT for the segment. ! 166: aaplAddress[ i ] = PEMapSegment( map->physical, 0x10000000); ! 167: if( aaplAddress[ i ] != map->physical) { ! 168: IOLog("%s: NDRV needs 1-1 mapping\n", logname); ! 169: err = IO_R_VM_FAILURE; ! 170: break; ! 171: } ! 172: ! 173: #if 0 ! 174: // Declare range for pmap'ing into user space ! 175: // Shouldn't be here but it's too expensive to do it for all devices ! 176: if( map->length > 0x01000000) ! 177: map->length = 0x01000000; // greed hack ! 178: err = pmap_add_physical_memory( map->physical, ! 179: map->physical + map->length, FALSE, PTE_WIMG_IO); ! 180: if(err) ! 181: kprintf("%s: pmap_add_physical_memory: %d for 0x%08x - 0x%08x\n", ! 182: logname, err, map->physical, map->physical + map->length); ! 183: #endif ! 184: } ! 185: if( err) ! 186: continue; ! 187: ! 188: // NDRV aperture vectors ! 189: [propTable deleteProperty:"AAPL,address"]; ! 190: err = [propTable createProperty:"AAPL,address" flags:0 ! 191: value:aaplAddress length:(numMaps * sizeof( IOLogicalAddress))]; ! 192: if( err) ! 193: continue; ! 194: ! 195: // interrupt tree for NDRVs - not really ! 196: err = [propTable createProperty:"driver-ist" flags:0 ! 197: value:intsProperty length:sizeof( intsProperty)]; ! 198: ! 199: // tell kmDevice if it's on the boot console, it's going away ! 200: if( consoleDevice) ! 201: [kmId unregisterDisplay:nil]; ! 202: ! 203: err = [self checkDriver]; ! 204: if( err) { ! 205: kprintf("%s: Not usable\n", logname ); ! 206: if( err == -999) ! 207: IOLog("%s: Driver is incompatible.\n", logname ); ! 208: continue; ! 209: } ! 210: ! 211: if (nil == [super initFromDeviceDescription:deviceDescription]) ! 212: continue; ! 213: err = [self open]; ! 214: if( err) ! 215: continue; ! 216: ! 217: #if 0 ! 218: if ([self startIOThread] != IO_R_SUCCESS) ! 219: kprintf("startIOThread FAIL\n"); ! 220: [self enableAllInterrupts]; ! 221: #endif ! 222: ! 223: me = self; // Success ! 224: ! 225: } while( false); ! 226: ! 227: if( me == nil) ! 228: [super free]; ! 229: ! 230: return( me); ! 231: } ! 232: ! 233: ! 234: - free ! 235: { ! 236: if (transferTable != 0) { ! 237: IOFree(transferTable, 256 * sizeof( ColorSpec)); ! 238: } ! 239: return [super free]; ! 240: } ! 241: ! 242: ! 243: - (IOReturn) ! 244: getDisplayModeTiming:(IOFBIndex)connectIndex mode:(IOFBDisplayModeID)modeID ! 245: timingInfo:(IOFBTimingInformation *)info connectFlags:(UInt32 *)flags ! 246: { ! 247: VDTimingInfoRec timingInfo; ! 248: OSStatus err; ! 249: ! 250: timingInfo.csTimingMode = modeID; ! 251: timingInfo.csTimingFormat = kDeclROMtables; // in case the driver doesn't do it ! 252: err = [self doStatus:cscGetModeTiming params:&timingInfo]; ! 253: if( err == noErr) { ! 254: if( timingInfo.csTimingFormat == kDeclROMtables) ! 255: info->standardTimingID = timingInfo.csTimingData; ! 256: else ! 257: info->standardTimingID = timingInvalid; ! 258: *flags = timingInfo.csTimingFlags; ! 259: return( [super getDisplayModeTiming:connectIndex mode:modeID timingInfo:info connectFlags:flags]); ! 260: } ! 261: *flags = 0; ! 262: return( IO_R_UNDEFINED_MODE); ! 263: } ! 264: ! 265: - (IOReturn) ! 266: getDisplayModeByIndex:(IOFBIndex)modeIndex displayMode:(IOFBDisplayModeID *)displayModeID ! 267: { ! 268: ! 269: // unfortunately, there is no "kDisplayModeIDFindSpecific" ! 270: if( modeIndex <= cachedModeIndex) { ! 271: cachedModeID = kDisplayModeIDFindFirstResolution; ! 272: cachedModeIndex = -1; ! 273: } ! 274: ! 275: cachedVDResolution.csPreviousDisplayModeID = cachedModeID; ! 276: ! 277: while( ! 278: (noErr == [self doStatus:cscGetNextResolution params:&cachedVDResolution]) ! 279: && ((SInt32) cachedVDResolution.csDisplayModeID > 0) ) { ! 280: ! 281: cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID; ! 282: ! 283: if( modeIndex == ++cachedModeIndex) { ! 284: cachedModeID = cachedVDResolution.csDisplayModeID; ! 285: *displayModeID = cachedModeID; ! 286: return( noErr); ! 287: } ! 288: } ! 289: cachedModeIndex = 0x7fffffff; ! 290: return( IO_R_UNDEFINED_MODE); ! 291: } ! 292: ! 293: ! 294: - (IOReturn) ! 295: getResInfoForMode:(IOFBDisplayModeID)modeID info:(VDResolutionInfoRec **)theInfo ! 296: { ! 297: ! 298: *theInfo = &cachedVDResolution; ! 299: ! 300: if( cachedVDResolution.csDisplayModeID == modeID) ! 301: return( noErr); ! 302: ! 303: cachedVDResolution.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution; ! 304: ! 305: while( ! 306: (noErr == [self doStatus:cscGetNextResolution params:&cachedVDResolution]) ! 307: && ((SInt32) cachedVDResolution.csDisplayModeID > 0) ) ! 308: { ! 309: cachedVDResolution.csPreviousDisplayModeID = cachedVDResolution.csDisplayModeID; ! 310: if( cachedVDResolution.csDisplayModeID == modeID) ! 311: return( noErr); ! 312: } ! 313: cachedVDResolution.csDisplayModeID = -1; ! 314: return( IO_R_UNDEFINED_MODE); ! 315: } ! 316: ! 317: - (IOReturn) ! 318: getDisplayModeInformation:(IOFBDisplayModeID)modeID info:(IOFBDisplayModeInformation *)info ! 319: { ! 320: IOReturn err; ! 321: VDResolutionInfoRec * resInfo; ! 322: ! 323: do { ! 324: err = [self getResInfoForMode:modeID info:&resInfo]; ! 325: if( err) ! 326: continue; ! 327: info->displayModeID = resInfo->csDisplayModeID; ! 328: info->maxDepthIndex = resInfo->csMaxDepthMode - kDepthMode1; ! 329: info->nominalWidth = resInfo->csHorizontalPixels; ! 330: info->nominalHeight = resInfo->csVerticalLines; ! 331: info->refreshRate = resInfo->csRefreshRate; ! 332: return( noErr); ! 333: } while( false); ! 334: ! 335: return( IO_R_UNDEFINED_MODE); ! 336: } ! 337: ! 338: ! 339: - (IOReturn) ! 340: getPixelInformationForDisplayMode:(IOFBDisplayModeID)modeID andDepthIndex:(IOFBIndex)depthIndex ! 341: pixelInfo:(IOFBPixelInformation *)info ! 342: { ! 343: SInt32 err; ! 344: ! 345: VDVideoParametersInfoRec pixelParams; ! 346: VPBlock pixelInfo; ! 347: VDResolutionInfoRec * resInfo; ! 348: ! 349: do { ! 350: err = [self getResInfoForMode:modeID info:&resInfo]; ! 351: if( err) ! 352: continue; ! 353: pixelParams.csDisplayModeID = modeID; ! 354: pixelParams.csDepthMode = depthIndex + kDepthMode1; ! 355: pixelParams.csVPBlockPtr = &pixelInfo; ! 356: err = [self doStatus:cscGetVideoParameters params:&pixelParams]; ! 357: if( err) ! 358: continue; ! 359: ! 360: info->flags = 0; ! 361: info->rowBytes = pixelInfo.vpRowBytes & 0x7fff; ! 362: info->width = pixelInfo.vpBounds.right; ! 363: info->height = pixelInfo.vpBounds.bottom; ! 364: info->refreshRate = resInfo->csRefreshRate; ! 365: info->pageCount = 1; ! 366: info->pixelType = (pixelInfo.vpPixelSize <= 8) ? ! 367: kIOFBRGBCLUTPixelType : kIOFBDirectRGBPixelType; ! 368: info->bitsPerPixel = pixelInfo.vpPixelSize; ! 369: // info->channelMasks = ! 370: ! 371: } while( false); ! 372: ! 373: return( err); ! 374: } ! 375: ! 376: - (IOReturn) open ! 377: { ! 378: IOReturn err; ! 379: ! 380: do { ! 381: err = [self checkDriver]; ! 382: if( err) ! 383: continue; ! 384: err = [super open]; ! 385: ! 386: } while( false); ! 387: ! 388: return( err); ! 389: } ! 390: ! 391: - (IOReturn) checkDriver ! 392: { ! 393: OSStatus err = noErr; ! 394: struct DriverInitInfo initInfo; ! 395: CntrlParam pb; ! 396: IOFBConfiguration config; ! 397: VDClutBehavior clutSetting = kSetClutAtSetEntries; ! 398: ! 399: if( ndrvState == 0) { ! 400: do { ! 401: initInfo.refNum = 0xffcd; // ...sure. ! 402: MAKE_REG_ENTRY(initInfo.deviceEntry, ioDevice) ! 403: ! 404: err = NDRVDoDriverIO( doDriverIO, 0, &initInfo, kInitializeCommand, kImmediateIOCommandKind ); ! 405: if( err) continue; ! 406: ! 407: err = NDRVDoDriverIO( doDriverIO, 0, &pb, kOpenCommand, kImmediateIOCommandKind ); ! 408: if( err) continue; ! 409: ! 410: } while( false); ! 411: if( err) ! 412: return( err); ! 413: ! 414: { ! 415: VDVideoParametersInfoRec pixelParams; ! 416: VPBlock pixelInfo; ! 417: VDResolutionInfoRec vdRes; ! 418: UInt32 size; ! 419: ! 420: vramLength = 0; ! 421: vdRes.csPreviousDisplayModeID = kDisplayModeIDFindFirstResolution; ! 422: while( ! 423: (noErr == [self doStatus:cscGetNextResolution params:&vdRes]) ! 424: && ((SInt32) vdRes.csDisplayModeID > 0) ) ! 425: { ! 426: ! 427: pixelParams.csDisplayModeID = vdRes.csDisplayModeID; ! 428: pixelParams.csDepthMode = vdRes.csMaxDepthMode; ! 429: pixelParams.csVPBlockPtr = &pixelInfo; ! 430: err = [self doStatus:cscGetVideoParameters params:&pixelParams]; ! 431: if( err) ! 432: continue; ! 433: ! 434: // Control hangs its framebuffer off the end of the aperture to support ! 435: // 832 x 624 @ 32bpp. The commented out version will correctly calculate ! 436: // the vram length, but DPS needs the full extent to be mapped, so we'll ! 437: // end up mapping an extra page that will address vram through the little ! 438: // endian aperture. No other drivers like this known. ! 439: #if 1 ! 440: size = 0x40 + pixelInfo.vpBounds.bottom * (pixelInfo.vpRowBytes & 0x7fff); ! 441: #else ! 442: size = ( (pixelInfo.vpBounds.right * pixelInfo.vpPixelSize) / 8) // last line ! 443: + (pixelInfo.vpBounds.bottom - 1) * (pixelInfo.vpRowBytes & 0x7fff); ! 444: #endif ! 445: if( size > vramLength) ! 446: vramLength = size; ! 447: ! 448: vdRes.csPreviousDisplayModeID = vdRes.csDisplayModeID; ! 449: } ! 450: ! 451: err = [self getConfiguration:&config]; ! 452: vramBase = config.physicalFramebuffer; ! 453: vramLength = (vramLength + (vramBase & 0xffff) + 0xffff) & 0xffff0000; ! 454: vramBase &= 0xffff0000; ! 455: ! 456: #if 1 ! 457: // Declare range for pmap'ing into user space ! 458: // Shouldn't be here but it's too expensive to do it for all devices ! 459: err = pmap_add_physical_memory( vramBase, ! 460: vramBase + vramLength, FALSE, PTE_WIMG_IO); ! 461: if(err) ! 462: kprintf("%s: pmap_add_physical_memory: %d for 0x%08x - 0x%08x\n", ! 463: [self name], err, vramBase, vramBase + vramLength ); ! 464: #endif ! 465: } ! 466: ! 467: // Set CLUT immediately since there's no VBL. ! 468: [self doControl:cscSetClutBehavior params:&clutSetting]; ! 469: ! 470: ndrvState = 1; ! 471: } ! 472: return( noErr); ! 473: } ! 474: ! 475: ! 476: - (IOReturn) ! 477: setDisplayMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex page:(IOFBIndex)pageIndex; ! 478: { ! 479: SInt32 err; ! 480: VDSwitchInfoRec switchInfo; ! 481: VDPageInfo pageInfo; ! 482: ! 483: switchInfo.csData = modeID; ! 484: switchInfo.csMode = depthIndex + kDepthMode1; ! 485: switchInfo.csPage = pageIndex; ! 486: err = [self doControl:cscSwitchMode params:&switchInfo]; ! 487: if(err) ! 488: IOLog("%s: cscSwitchMode:%d\n",[self name],(int)err); ! 489: ! 490: // duplicate QD InitGDevice ! 491: pageInfo.csMode = switchInfo.csMode; ! 492: pageInfo.csData = 0; ! 493: pageInfo.csPage = pageIndex; ! 494: [self doControl:cscSetMode params:&pageInfo]; ! 495: [self doControl:cscGrayPage params:&pageInfo]; ! 496: ! 497: return( err); ! 498: } ! 499: ! 500: - (IOReturn) ! 501: setStartupMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex; ! 502: { ! 503: SInt32 err; ! 504: VDSwitchInfoRec switchInfo; ! 505: ! 506: switchInfo.csData = modeID; ! 507: switchInfo.csMode = depthIndex + kDepthMode1; ! 508: err = [self doControl:cscSavePreferredConfiguration params:&switchInfo]; ! 509: return( err); ! 510: } ! 511: ! 512: - (IOReturn) ! 513: getStartupMode:(IOFBDisplayModeID *)modeID depth:(IOFBIndex *)depthIndex ! 514: { ! 515: SInt32 err; ! 516: VDSwitchInfoRec switchInfo; ! 517: ! 518: err = [self doStatus:cscGetPreferredConfiguration params:&switchInfo]; ! 519: if( err == noErr) { ! 520: *modeID = switchInfo.csData; ! 521: *depthIndex = switchInfo.csMode - kDepthMode1; ! 522: } ! 523: return( err); ! 524: } ! 525: ! 526: ! 527: - (IOReturn) ! 528: getConfiguration:(IOFBConfiguration *)config; ! 529: { ! 530: IOReturn err; ! 531: VDSwitchInfoRec switchInfo; ! 532: VDGrayRecord grayRec; ! 533: ! 534: bzero( config, sizeof( IOFBConfiguration)); ! 535: ! 536: grayRec.csMode = 0; // turn off luminance map ! 537: err = [self doControl:cscSetGray params:&grayRec]; ! 538: if( (noErr == err) && (0 != grayRec.csMode)) ! 539: // driver refused => mono display ! 540: config->flags |= kFBLuminanceMapped; ! 541: ! 542: err = [self doStatus:cscGetCurMode params:&switchInfo]; ! 543: config->displayMode = switchInfo.csData; ! 544: config->depth = switchInfo.csMode - kDepthMode1; ! 545: config->page = switchInfo.csPage; ! 546: config->physicalFramebuffer = ((UInt32) switchInfo.csBaseAddr); ! 547: config->mappedFramebuffer = config->physicalFramebuffer; // assuming 1-1 ! 548: ! 549: return( err); ! 550: } ! 551: ! 552: - (IOReturn) ! 553: getApertureInformationByIndex:(IOFBIndex)apertureIndex ! 554: apertureInfo:(IOFBApertureInformation *)apertureInfo ! 555: { ! 556: IOReturn err; ! 557: ! 558: if( apertureIndex == 0) { ! 559: apertureInfo->physicalAddress = vramBase; ! 560: apertureInfo->mappedAddress = vramBase; ! 561: apertureInfo->length = vramLength; ! 562: apertureInfo->cacheMode = 0; ! 563: apertureInfo->type = kIOFBGraphicsMemory; ! 564: err = noErr; ! 565: } else ! 566: err = IO_R_UNDEFINED_MODE; ! 567: ! 568: return( err); ! 569: } ! 570: ! 571: #if 0 ! 572: ! 573: - (IOReturn) getInterruptFunctionsTV:(UInt32)member ! 574: refCon:(void **)refCon, ! 575: handler:(TVector *) handler, ! 576: enabler:(TVector *) enabler, ! 577: disabler:(TVector *) disabler ! 578: ! 579: { ! 580: OSStatus err; ! 581: ! 582: err = [interrupt getInterruptFunctionsTV:member refCon:refCon handler:handler ! 583: enabler:enabler disabler:disabler]; ! 584: return( err); ! 585: } ! 586: ! 587: ! 588: SInt32 StdIntHandler( InterruptSetMember setMember, void *refCon, UInt32 theIntCount) ! 589: { ! 590: return( kIsrIsComplete); ! 591: } ! 592: void StdIntEnabler( InterruptSetMember setMember, void *refCon) ! 593: { ! 594: return; ! 595: } ! 596: Boolean StdIntDisabler( InterruptSetMember setMember, void *refCon) ! 597: { ! 598: return( false); ! 599: } ! 600: ! 601: ! 602: - (IOReturn) setInterruptFunctionsTV:(UInt32)member ! 603: refCon:(void *)refCon, ! 604: handler:(TVector *) handler, ! 605: enabler:(TVector *) enabler, ! 606: disabler:(TVector *) disabler ! 607: { ! 608: ! 609: if( handler != NULL) ! 610: currentIntHandler = handler; ! 611: if( enabler != NULL) ! 612: currentIntEnabler = enabler; ! 613: if( disabler != NULL) ! 614: currentIntDisabler = disabler; ! 615: ! 616: err = [interrupt setInterruptFunctions:member refCon:refCon handler:currentIntHandler ! 617: enabler:enabler disabler:disabler]; ! 618: ! 619: } ! 620: ! 621: - (IOReturn) setInterruptFunctions:(UInt32)member ! 622: refCon:(void *)refCon, ! 623: handler:(InterruptHandler) handler, ! 624: enabler:(InterruptEnabler) enabler, ! 625: disabler:(InterruptDisabler) disabler ! 626: ! 627: ! 628: ! 629: - (IOReturn) getInterruptFunctions:(UInt32)member ! 630: refCon:(void **)refCon, ! 631: handler:(InterruptHandler *) handler, ! 632: enabler:(InterruptEnabler *) enabler, ! 633: disabler:(InterruptDisabler *) disabler ! 634: ! 635: #endif ! 636: ! 637: ////////////////////////////////////////////////////////////////////////////////////////// ! 638: ! 639: - (IOReturn) getAppleSense:(IOFBIndex)connectIndex info:(IOFBAppleSenseInfo *)info; ! 640: { ! 641: OSStatus err; ! 642: VDDisplayConnectInfoRec displayConnect; ! 643: ! 644: err = [self doStatus:cscGetConnection params:&displayConnect]; ! 645: if( err) ! 646: return( err); ! 647: ! 648: if( displayConnect.csConnectFlags & ((1<<kReportsTagging) | (1<<kTaggingInfoNonStandard)) ! 649: != ((1<<kReportsTagging)) ) ! 650: ! 651: err = IO_R_UNSUPPORTED; ! 652: ! 653: else { ! 654: // info->standardDisplayType = displayConnect.csDisplayType; ! 655: info->primarySense = displayConnect.csConnectTaggedType; ! 656: info->extendedSense = displayConnect.csConnectTaggedData; ! 657: if( (info->primarySense == 0) && (info->extendedSense == 6)) { ! 658: info->primarySense = kRSCSix; ! 659: info->extendedSense = kESCSixStandard; ! 660: } ! 661: if( (info->primarySense == 0) && (info->extendedSense == 4)) { ! 662: info->primarySense = kRSCFour; ! 663: info->extendedSense = kESCFourNTSC; ! 664: } ! 665: } ! 666: return( err); ! 667: } ! 668: ! 669: - (BOOL) hasDDCConnect:(IOFBIndex)connectIndex ! 670: { ! 671: OSStatus err; ! 672: VDDisplayConnectInfoRec displayConnect; ! 673: enum { kNeedFlags = (1<<kReportsDDCConnection) | (1<<kHasDDCConnection) }; ! 674: ! 675: err = [self doStatus:cscGetConnection params:&displayConnect]; ! 676: if( err) ! 677: return( NO); ! 678: ! 679: return( (displayConnect.csConnectFlags & kNeedFlags) == kNeedFlags ); ! 680: } ! 681: ! 682: - (IOReturn) getDDCBlock:(IOFBIndex)connectIndex blockNumber:(UInt32)num blockType:(OSType)type ! 683: options:(UInt32)options data:(UInt8 *)data length:(ByteCount *)length ! 684: { ! 685: OSStatus err = 0; ! 686: VDDDCBlockRec ddcRec; ! 687: ByteCount actualLength = *length; ! 688: ! 689: ddcRec.ddcBlockNumber = num; ! 690: ddcRec.ddcBlockType = type; ! 691: ddcRec.ddcFlags = options; ! 692: ! 693: err = [self doStatus:cscGetDDCBlock params:&ddcRec]; ! 694: ! 695: if( err == noErr) { ! 696: ! 697: actualLength = (actualLength < kDDCBlockSize) ? actualLength : kDDCBlockSize; ! 698: bcopy( ddcRec.ddcBlockData, data, actualLength); ! 699: *length = actualLength; ! 700: } ! 701: return( err); ! 702: } ! 703: ! 704: ////////////////////////////////////////////////////////////////////////////////////////// ! 705: ! 706: - (IOReturn)getIntValues:(unsigned *)parameterArray ! 707: forParameter:(IOParameterName)parameterName ! 708: count:(unsigned int *)count ! 709: { ! 710: ! 711: if (strcmp(parameterName, "IOGetTransferTable") == 0) { ! 712: return( [self getTransferTable:¶meterArray[0] count:count] ); ! 713: ! 714: } else ! 715: return [super getIntValues:parameterArray ! 716: forParameter:parameterName ! 717: count:count]; ! 718: } ! 719: ! 720: ! 721: ! 722: ////////////////////////////////////////////////////////////////////////////////////////// ! 723: // IOCallDeviceMethods: ! 724: ! 725: // Should be in NDRV class? ! 726: - (IOReturn) IONDRVGetDriverName:(char *)outputParams size:(unsigned *) outputCount ! 727: { ! 728: char * name; ! 729: UInt32 len, plen; ! 730: ! 731: name = theDriverDesc->driverOSRuntimeInfo.driverName; ! 732: ! 733: plen = *(name++); ! 734: len = *outputCount - 1; ! 735: *outputCount = plen + 1; ! 736: if( plen < len) ! 737: len = plen; ! 738: strncpy( outputParams, name, len); ! 739: outputParams[ len ] = 0; ! 740: ! 741: return( noErr); ! 742: } ! 743: ! 744: - (IOReturn) IONDRVDoControl:(UInt32 *)inputParams inputSize:(unsigned) inputCount ! 745: params:(void *)outputParams outputSize:(unsigned *) outputCount ! 746: privileged:(host_priv_t *)privileged ! 747: { ! 748: IOReturn err = noErr; ! 749: UInt32 callSelect; ! 750: ! 751: if( privileged == NULL) ! 752: err = IO_R_PRIVILEGE; ! 753: else { ! 754: callSelect = *inputParams; ! 755: err = [self doControl:callSelect params:(inputParams + 1 )]; ! 756: bcopy( inputParams, outputParams, *outputCount); ! 757: } ! 758: return( err); ! 759: } ! 760: ! 761: ////////////////////////////////////////////////////////////////////////////////////////// ! 762: ! 763: - (IOReturn) IONDRVDoStatus:(UInt32 *)inputParams inputSize:(unsigned) inputCount ! 764: params:(void *)outputParams outputSize:(unsigned *) outputCount ! 765: { ! 766: IOReturn err = noErr; ! 767: UInt32 callSelect; ! 768: ! 769: callSelect = *inputParams; ! 770: err = [self doStatus:callSelect params:(inputParams + 1 )]; ! 771: bcopy( inputParams, outputParams, *outputCount); ! 772: return( err); ! 773: ! 774: } ! 775: ! 776: @end ! 777: ! 778: ////////////////////////////////////////////////////////////////////////////////////////// ! 779: // DACrap ! 780: ! 781: @implementation IONDRVFramebuffer (ProgramDAC) ! 782: ! 783: - setTheTable ! 784: { ! 785: IOReturn err; ! 786: ColorSpec * table = transferTable; ! 787: VDSetEntryRecord setEntryRec; ! 788: int i, code; ! 789: ! 790: if( transferTableCount != 0) { ! 791: if( brightnessLevel != EV_SCREEN_MAX_BRIGHTNESS) { ! 792: if( !scaledTable) ! 793: scaledTable = IOMalloc( 256 * sizeof( ColorSpec)); ! 794: if( scaledTable) { ! 795: for( i = 0; i < transferTableCount; i++ ) { ! 796: scaledTable[ i ].rgb.red = EV_SCALE_BRIGHTNESS( brightnessLevel, table[ i ].rgb.red); ! 797: scaledTable[ i ].rgb.green = EV_SCALE_BRIGHTNESS( brightnessLevel, table[ i ].rgb.green); ! 798: scaledTable[ i ].rgb.blue = EV_SCALE_BRIGHTNESS( brightnessLevel, table[ i ].rgb.blue); ! 799: } ! 800: table = scaledTable; ! 801: } ! 802: } else { ! 803: if( scaledTable) { ! 804: IOFree( scaledTable, transferTableCount * sizeof( ColorSpec)); ! 805: scaledTable = 0; ! 806: } ! 807: } ! 808: ! 809: setEntryRec.csTable = table; ! 810: setEntryRec.csStart = 0; ! 811: setEntryRec.csCount = transferTableCount - 1; ! 812: if( [self displayInfo]->bitsPerPixel == IO_8BitsPerPixel) ! 813: code = cscSetEntries; ! 814: else ! 815: code = cscDirectSetEntries; ! 816: err = [self doControl:code params:&setEntryRec]; ! 817: } ! 818: return self; ! 819: } ! 820: ! 821: - setBrightness:(int)level token:(int)t ! 822: { ! 823: if ((level < EV_SCREEN_MIN_BRIGHTNESS) || ! 824: (level > EV_SCREEN_MAX_BRIGHTNESS)){ ! 825: IOLog("Display: Invalid arg to setBrightness: %d\n", ! 826: level); ! 827: return nil; ! 828: } ! 829: brightnessLevel = level; ! 830: [self setTheTable]; ! 831: return self; ! 832: } ! 833: ! 834: #define Expand8To16(x) (((x) << 8) | (x)) ! 835: ! 836: ! 837: - setTransferTable:(const unsigned int *)table count:(int)count ! 838: { ! 839: ! 840: // no checking table count vs. depth ?? ! 841: ! 842: int k; ! 843: IOBitsPerPixel bpp; ! 844: IOColorSpace cspace; ! 845: VDGammaRecord gammaRec; ! 846: ! 847: bpp = [self displayInfo]->bitsPerPixel; ! 848: cspace = [self displayInfo]->colorSpace; ! 849: ! 850: if( table) { ! 851: transferTableCount = count; ! 852: if (bpp == IO_8BitsPerPixel && cspace == IO_OneIsWhiteColorSpace) { ! 853: for (k = 0; k < count; k++) { ! 854: transferTable[k].rgb.red = transferTable[k].rgb.green = transferTable[k].rgb.blue ! 855: = Expand8To16(table[k] & 0xFF); ! 856: } ! 857: } else if (cspace == IO_RGBColorSpace && ! 858: ((bpp == IO_8BitsPerPixel) || ! 859: (bpp == IO_15BitsPerPixel) || ! 860: (bpp == IO_24BitsPerPixel))) { ! 861: for (k = 0; k < count; k++) { ! 862: transferTable[k].rgb.red = Expand8To16((table[k] >> 24) & 0xFF); ! 863: transferTable[k].rgb.green = Expand8To16((table[k] >> 16) & 0xFF); ! 864: transferTable[k].rgb.blue = Expand8To16((table[k] >> 8) & 0xFF); ! 865: } ! 866: } else { ! 867: transferTableCount = 0; ! 868: } ! 869: } ! 870: ! 871: if( NO == gammaKilled) { ! 872: gammaRec.csGTable = 0; ! 873: [self doControl:cscSetGamma params:&gammaRec]; ! 874: gammaKilled = YES; ! 875: } ! 876: ! 877: [self setTheTable]; ! 878: return self; ! 879: } ! 880: ! 881: - (IOReturn)getTransferTable:(unsigned int *)table count:(int *)count ! 882: { ! 883: int k; ! 884: ! 885: if( *count != transferTableCount) ! 886: return( IO_R_INVALID_ARG); ! 887: ! 888: for (k = 0; k < transferTableCount; k++) { ! 889: table[k] = ((transferTable[k].rgb.red << 16) & 0xff000000) ! 890: | ((transferTable[k].rgb.green << 8) & 0xff0000) ! 891: | ((transferTable[k].rgb.blue) & 0xff00) ! 892: | ((transferTable[k].rgb.blue >> 8) & 0xff); ! 893: } ! 894: return( IO_R_SUCCESS); ! 895: } ! 896: ! 897: // Apple style CLUT - pass thru gamma table ! 898: ! 899: - (IOReturn) ! 900: setCLUT:(IOFBColorEntry *) colors index:(UInt32)index numEntries:(UInt32)numEntries ! 901: brightness:(IOFixed)brightness options:(IOOptionBits)options ! 902: { ! 903: IOReturn err; ! 904: VDSetEntryRecord setEntryRec; ! 905: int code; ! 906: ! 907: setEntryRec.csTable = (ColorSpec *)colors; ! 908: setEntryRec.csStart = index; ! 909: setEntryRec.csCount = numEntries - 1; ! 910: if( [self displayInfo]->bitsPerPixel == IO_8BitsPerPixel) ! 911: code = cscSetEntries; ! 912: else ! 913: code = cscDirectSetEntries; ! 914: err = [self doControl:code params:&setEntryRec]; ! 915: ! 916: return( err); ! 917: ! 918: } ! 919: ! 920: #if 0 ! 921: - (void) interruptOccurred ! 922: { ! 923: kprintf("\n[%s]\n", [self name]); ! 924: [self enableAllInterrupts]; ! 925: } ! 926: #endif ! 927: ! 928: @end ! 929: ! 930: ////////////////////////////////////////////////////////////////////////////////////////// ! 931: ! 932: // OpenFirmware shim ! 933: ! 934: enum { kTheDisplayMode = 10 }; ! 935: ! 936: @implementation IOOFFramebuffer ! 937: ! 938: //======================================================================= ! 939: ! 940: - initFromDeviceDescription:(IOPCIDevice *) ioDevice ! 941: { ! 942: id me = nil; ! 943: kern_return_t err = 0; ! 944: UInt32 i; ! 945: UInt32 numMaps = 8; ! 946: IOApertureInfo maps[ numMaps ]; // FIX ! 947: IOApertureInfo * map; ! 948: ! 949: do { ! 950: numMaps = 8; ! 951: err = [ioDevice getApertures:maps items:&numMaps]; ! 952: if( err) ! 953: continue; ! 954: ! 955: err = -1; ! 956: for( i = 0, map = maps; i < numMaps; i++, map++) { ! 957: ! 958: if( (((UInt32)bootDisplayInfo.frameBuffer) >= ((UInt32)map->physical)) ! 959: && (((UInt32)bootDisplayInfo.frameBuffer) < (map->length + (UInt32)map->physical)) ) { ! 960: ! 961: // Declare range for pmap'ing into user space ! 962: // Shouldn't be here but it's too expensive to do it for all devices ! 963: err = pmap_add_physical_memory( map->physical, ! 964: map->physical + map->length, FALSE, PTE_WIMG_IO); ! 965: if(err) ! 966: kprintf("%s: pmap_add_physical_memory:%d for 0x%08x - 0x%08x\n", ! 967: [self name], err, map->physical, map->physical + map->length); ! 968: } ! 969: } ! 970: if( err) ! 971: continue; ! 972: ! 973: if (nil == [super initFromDeviceDescription:ioDevice]) ! 974: continue; ! 975: err = [self open]; ! 976: if( err) ! 977: continue; ! 978: ! 979: me = self; // Success ! 980: ! 981: } while( false); ! 982: ! 983: if( me == nil) ! 984: [super free]; ! 985: ! 986: return( me); ! 987: } ! 988: ! 989: - (IOReturn) ! 990: getDisplayModeByIndex:(IOFBIndex)modeIndex displayMode:(IOFBDisplayModeID *)displayModeID ! 991: { ! 992: if( modeIndex) ! 993: return( IO_R_UNDEFINED_MODE); ! 994: *displayModeID = kTheDisplayMode; ! 995: return( noErr); ! 996: } ! 997: ! 998: - (IOReturn) ! 999: getDisplayModeInformation:(IOFBDisplayModeID)modeID info:(IOFBDisplayModeInformation *)info ! 1000: { ! 1001: if( modeID == kTheDisplayMode) { ! 1002: info->displayModeID = modeID; ! 1003: info->maxDepthIndex = 0; ! 1004: info->nominalWidth = bootDisplayInfo.width; ! 1005: info->nominalHeight = bootDisplayInfo.height; ! 1006: info->refreshRate = bootDisplayInfo.refreshRate << 16; ! 1007: return( noErr); ! 1008: } ! 1009: return( IO_R_UNDEFINED_MODE); ! 1010: } ! 1011: ! 1012: ! 1013: - (IOReturn) ! 1014: getPixelInformationForDisplayMode:(IOFBDisplayModeID)modeID andDepthIndex:(IOFBIndex)depthIndex ! 1015: pixelInfo:(IOFBPixelInformation *)info ! 1016: { ! 1017: ! 1018: if( (modeID == kTheDisplayMode) && (depthIndex == 0)) { ! 1019: ! 1020: info->flags = 0; ! 1021: info->rowBytes = bootDisplayInfo.rowBytes; ! 1022: info->width = bootDisplayInfo.width; ! 1023: info->height = bootDisplayInfo.height; ! 1024: info->refreshRate = bootDisplayInfo.refreshRate << 16; ! 1025: info->pageCount = 1; ! 1026: info->pixelType = kIOFBRGBCLUTPixelType; ! 1027: info->bitsPerPixel = 8; ! 1028: // info->channelMasks = ! 1029: return( noErr); ! 1030: } ! 1031: return( IO_R_UNDEFINED_MODE); ! 1032: } ! 1033: ! 1034: - (IOReturn) ! 1035: setDisplayMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex page:(IOFBIndex)pageIndex ! 1036: { ! 1037: if( (modeID == kTheDisplayMode) && (depthIndex == 0) && (pageIndex == 0) ) ! 1038: return( noErr); ! 1039: else ! 1040: return( IO_R_UNDEFINED_MODE); ! 1041: } ! 1042: ! 1043: ! 1044: - (IOReturn) ! 1045: getStartupMode:(IOFBDisplayModeID *)modeID depth:(IOFBIndex *)depthIndex ! 1046: { ! 1047: *modeID = kTheDisplayMode; ! 1048: *depthIndex = 0; ! 1049: ! 1050: return( noErr); ! 1051: } ! 1052: ! 1053: ! 1054: - (IOReturn) ! 1055: getConfiguration:(IOFBConfiguration *)config ! 1056: { ! 1057: bzero( config, sizeof( IOFBConfiguration)); ! 1058: ! 1059: config->displayMode = kTheDisplayMode; ! 1060: config->depth = 0; ! 1061: config->page = 0; ! 1062: config->physicalFramebuffer = (IOPhysicalAddress) bootDisplayInfo.frameBuffer; ! 1063: config->mappedFramebuffer = (IOVirtualAddress) bootDisplayInfo.frameBuffer; // assuming 1-1 ! 1064: ! 1065: return( noErr); ! 1066: } ! 1067: ! 1068: - (IOReturn) ! 1069: getDisplayModeTiming:(IOFBIndex)connectIndex mode:(IOFBDisplayModeID)modeID ! 1070: timingInfo:(IOFBTimingInformation *)info connectFlags:(UInt32 *)flags ! 1071: { ! 1072: ! 1073: info->standardTimingID = timingInvalid; ! 1074: if( modeID == kTheDisplayMode) { ! 1075: *flags = kDisplayModeValidFlag | kDisplayModeSafeFlag | kDisplayModeDefaultFlag; ! 1076: return( noErr); ! 1077: } else { ! 1078: *flags = 0; ! 1079: return( IO_R_UNDEFINED_MODE); ! 1080: } ! 1081: } ! 1082: ! 1083: ! 1084: - setBrightness:(int)level token:(int)t ! 1085: { ! 1086: return self; ! 1087: } ! 1088: ! 1089: - setTransferTable:(const unsigned int *)table count:(int)count ! 1090: { ! 1091: return self; ! 1092: } ! 1093: ! 1094: - (IOReturn)getIntValues:(unsigned *)parameterArray ! 1095: forParameter:(IOParameterName)parameterName ! 1096: count:(unsigned int *)count ! 1097: { ! 1098: const UInt8 * clut; ! 1099: int i; ! 1100: extern const UInt8 appleClut8[ 256 * 3 ]; ! 1101: ! 1102: if( (0 == strcmp(parameterName, "IOGetTransferTable")) ! 1103: && (*count == 256)) { ! 1104: for( clut = appleClut8, i = 0; i < 256; i++, clut += 3) ! 1105: *(parameterArray++) = (clut[0] << 24) | (clut[1] << 16) | (clut[3] << 8) | 0xff; ! 1106: return( noErr); ! 1107: ! 1108: } else ! 1109: return [super getIntValues:parameterArray ! 1110: forParameter:parameterName ! 1111: count:count]; ! 1112: } ! 1113: ! 1114: @end ! 1115: ! 1116: ////////////////////////////////////////////////////////////////////////////////////////// ! 1117: ! 1118: // ATI patches. getStartupMode doesn't. ! 1119: ! 1120: @implementation IOATINDRV ! 1121: ! 1122: - (IOReturn) ! 1123: getStartupMode:(IOFBDisplayModeID *)modeID depth:(IOFBIndex *)depthIndex ! 1124: { ! 1125: ! 1126: IOReturn err; ! 1127: UInt16 * nvram; ! 1128: ByteCount propSize = 8; ! 1129: ! 1130: err = [[ioDevice propertyTable] getProperty:"Sime" flags:kReferenceProperty ! 1131: value:(void *)&nvram length:&propSize]; ! 1132: if( err == noErr) { ! 1133: *modeID = nvram[ 0 ]; // 1 is physDisplayMode ! 1134: *depthIndex = nvram[ 2 ] - kDepthMode1; ! 1135: } ! 1136: return( err); ! 1137: } ! 1138: ! 1139: @end ! 1140: ! 1141: // ix3D patches ! 1142: ! 1143: @implementation IOIX3DNDRV ! 1144: ! 1145: enum { ! 1146: kPantherOff_Regs = 0x06000000L, ! 1147: kPantherOff_SSTATUS = 0x000000ECL, ! 1148: }; ! 1149: ! 1150: void regwNoswap( volatile UInt8 * io, UInt32 regindex, UInt32 regdata) { ! 1151: ! 1152: *((UInt32 *)(io + regindex)) = (regdata); ! 1153: __asm__ volatile("eieio"); ! 1154: } ! 1155: ! 1156: void ! 1157: ix3dInterruptHandler( void * interrupt, void * istate, IOIX3DNDRV * vars ) ! 1158: { ! 1159: regwNoswap(vars->panther, kPantherOff_SSTATUS, 0x30 ); ! 1160: ! 1161: IOEnableInterrupt( interrupt); ! 1162: } ! 1163: ! 1164: - (BOOL) getHandler:(IOInterruptHandler *)handler ! 1165: level:(unsigned int *)ipl ! 1166: argument:(unsigned int *) arg ! 1167: forInterrupt:(unsigned int) localInterrupt ! 1168: { ! 1169: *handler = (IOInterruptHandler) ix3dInterruptHandler; ! 1170: *ipl = 30; ! 1171: *arg = (unsigned int)self; ! 1172: ! 1173: return( YES); ! 1174: } ! 1175: ! 1176: - (IOReturn) ! 1177: setDisplayMode:(IOFBDisplayModeID)modeID depth:(IOFBIndex)depthIndex page:(IOFBIndex)pageIndex ! 1178: { ! 1179: IOReturn err; ! 1180: ! 1181: [self disableInterrupt:0]; ! 1182: err = [super setDisplayMode:modeID depth:depthIndex page:pageIndex]; ! 1183: [self enableInterrupt:0]; ! 1184: return( err); ! 1185: } ! 1186: ! 1187: - (IOReturn) open ! 1188: { ! 1189: IOReturn err; ! 1190: IOFBConfiguration config; ! 1191: ! 1192: err = [super open]; ! 1193: if( err == noErr) { ! 1194: [self getConfiguration:&config]; ! 1195: panther = (volatile UInt8 *)(((UInt32)config.mappedFramebuffer) & 0xffff0000) ! 1196: + kPantherOff_Regs; ! 1197: [self enableInterrupt:0]; ! 1198: } ! 1199: return( err); ! 1200: } ! 1201: ! 1202: @end ! 1203: ! 1204: ! 1205:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.