|
|
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.