|
|
1.1 root 1: /*
2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) 1997 Apple Computer, Inc.
24: *
25: *
26: * HISTORY
27: *
28: * sdouglas 22 Oct 97 - first checked in.
29: * sdouglas 21 Jul 98 - start IOKit
30: * sdouglas 14 Dec 98 - start cpp.
31: */
32:
33:
34:
35: #include <IOKit/IOLib.h>
36: #include <libkern/c++/OSContainers.h>
37:
38: extern "C" {
39: #include <pexpert/pexpert.h>
40: };
41:
42: #include "IONDRV.h"
43: #include "IOPEFLoader.h"
44:
45: #define LOG if(1) kprintf
46:
47: #define USE_TREE_NDRVS 1
48: #define USE_ROM_NDRVS 1
49:
50:
51: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
52:
53: #define super OSObject
54:
55: OSDefineMetaClassAndStructors(IONDRV, OSObject)
56:
57: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
58:
59: IONDRV * IONDRV::instantiate( IOLogicalAddress container,
60: IOByteCount containerSize )
61: {
62: OSStatus err = 1;
63: IONDRV * inst;
64:
65: inst = new IONDRV;
66:
67: if( inst) do {
68: if( false == inst->init())
69: continue;
70:
71: err = PCodeOpen( (void *)container, containerSize, &inst->pcInst );
72: if( err)
73: continue;
74: err = PCodeInstantiate( inst->pcInst );
75: if( err)
76: continue;
77:
78: inst->getSymbol( "DoDriverIO",
79: (IOLogicalAddress *) &inst->fDoDriverIO );
80: if( kIOReturnSuccess == inst->getSymbol( "TheDriverDescription",
81: (IOLogicalAddress *) &inst->theDriverDesc )) {
82:
83: char * name;
84: int plen;
85:
86: name = (char *) inst->theDriverDesc->driverOSRuntimeInfo.driverName;
87: plen = name[ 0 ];
88: strncpy( name, name + 1, plen);
89: name[ plen ] = 0;
90:
91: kprintf("ndrv version %08x\n",
92: inst->theDriverDesc-> driverType.version);
93: }
94:
95: } while( false);
96:
97: if( inst && err) {
98: inst->release();
99: inst = 0;
100: }
101:
102: return( inst );
103: }
104:
105: void IONDRV::free( void )
106: {
107: super::free();
108: }
109:
110: IOReturn IONDRV::getSymbol( const char * symbolName,
111: IOLogicalAddress * address )
112: {
113: OSStatus err;
114:
115: err = PCodeFindExport( pcInst, symbolName,
116: (LogicalAddress *)address, NULL );
117: if( err)
118: *address = 0;
119:
120: return( err);
121: }
122:
123: #if 0
124: if( (err = NDRVGetShimClass( ioDevice, instance, 0, classNames ))
125: ) continue;
126: err = [propTable createProperty:"AAPL,dk_Driver Name" flags:0
127: value:classNames length:strlen( classNames) ];
128: err = [propTable createProperty:"AAPL,dk_Server Name" flags:0
129: value:classNames length:strlen( classNames) ];
130:
131: OSStatus NDRVGetShimClass( id ioDevice, NDRVInstance instance, UInt32 serviceIndex, char * className )
132: {
133: NDRVInstanceVars * ndrvInst = (NDRVInstanceVars *) instance;
134: OSStatus err;
135: static const char * driverDescProperty = "TheDriverDescription";
136: static const char * frameBufferShim = "IONDRVFramebuffer";
137: DriverDescription * desc;
138: UInt32 serviceType;
139:
140: className[ 0 ] = 0;
141: do {
142: err = PCodeFindExport( ndrvInst->pcInst, driverDescProperty, (IOLogicalAddress *)&desc, NULL );
143: if( err) continue;
144:
145: if( desc->driverDescSignature != kTheDescriptionSignature) {
146: err = -1;
147: continue;
148: }
149: if( serviceIndex >= desc->driverServices.nServices) {
150: err = -1;
151: continue;
152: }
153:
154: serviceType = desc->driverServices.service[ serviceIndex ].serviceType;
155: switch( desc->driverServices.service[ serviceIndex ].serviceCategory) {
156:
157: case kServiceCategoryNdrvDriver:
158: if( serviceType == kNdrvTypeIsVideo) {
159: strcpy( className, frameBufferShim);
160: break;
161: }
162: default:
163: err = -1;
164: }
165: } while( false);
166:
167: return( err);
168: }
169: #endif
170:
171:
172:
173: IOReturn IONDRV::doDriverIO( UInt32 commandID, void * contents,
174: UInt32 commandCode, UInt32 commandKind )
175: {
176: OSStatus err;
177:
178: if( 0 == fDoDriverIO)
179: return( kIOReturnUnsupported );
180:
181: err = CallTVector( /*AddressSpaceID*/ 0, (void *)commandID, contents,
182: (void *)commandCode, (void *)commandKind, /*p6*/ 0,
183: fDoDriverIO );
184:
185: #if 0
186: if( err) {
187: UInt32 i;
188: static const char * commands[] =
189: { "kOpenCommand", "kCloseCommand",
190: "kReadCommand", "kWriteCommand",
191: "kControlCommand", "kStatusCommand", "kKillIOCommand",
192: "kInitializeCommand", "kFinalizeCommand",
193: "kReplaceCommand", "kSupersededCommand" };
194:
195: LOG("Driver failed (%d) on %s : ", err, commands[ commandCode ] );
196:
197: switch( commandCode) {
198: case kControlCommand:
199: case kStatusCommand:
200: LOG("%d : ", ((UInt16 *)contents)[ 0x1a / 2 ]);
201: contents = ((void **)contents)[ 0x1c / 4 ];
202: for( i = 0; i<5; i++ )
203: LOG("%08x, ", ((UInt32 *)contents)[i] );
204: break;
205: }
206: LOG("\n");
207: }
208: #endif
209:
210: return( err);
211: }
212:
213:
214: IONDRV * IONDRV::fromRegistryEntry( IORegistryEntry * regEntry )
215: {
216: IOLogicalAddress pef = 0;
217: IOByteCount propSize = 0;
218: OSData * prop;
219: IONDRV * inst;
220:
221: inst = (IONDRV *) regEntry->getProperty("AAPL,ndrvInst");
222: if( inst) {
223: inst->retain();
224: return( inst );
225: }
226:
227: // -- only enable the boot display unless mmon flag is set
228: #if 0
229: int num;
230: prop = (OSData *) regEntry->getProperty( "AAPL,boot-display" );
231: if( (0 == prop) && (!PE_parse_boot_arg("mmon", &num)))
232: return( 0 );
233: #endif
234: // --
235:
236: prop = (OSData *) regEntry->getProperty( "driver,AAPL,MacOS,PowerPC" );
237: if( USE_TREE_NDRVS && prop) {
238: pef = (IOLogicalAddress) prop->getBytesNoCopy();
239: propSize = prop->getLength();
240: }
241:
242: // God awful hack:
243: // Some onboard devices don't have the ndrv in the tree. The booter
244: // can load & match PEF's but only from disk, not network boots.
245:
246: #if USE_ROM_NDRVS
247: if( !pef && (0 == strcmp( regEntry->getName(), "ATY,mach64_3DU")) ) {
248:
249: int * patch;
250:
251: patch = (int *) 0xffe88140;
252: propSize = 0x10a80;
253:
254: // Check ati PEF exists there
255: if( patch[ 0x1f0 / 4 ] == 'ATIU') {
256:
257: pef = (IOLogicalAddress) IOMalloc( propSize );
258: bcopy( (void *) patch, (void *) pef, propSize );
259: }
260: }
261:
262: if( !pef && (0 == strcmp( regEntry->getName(), "ATY,mach64_3DUPro")) ) {
263:
264: int * patch;
265:
266: patch = (int *) 0xffe99510;
267: propSize = 0x12008;
268: // Check ati PEF exists there
269: if( patch[ 0x1fc / 4 ] != 'ATIU') {
270:
271: // silk version
272: patch = (int *) 0xffe99550;
273: propSize = 0x12058;
274: if( patch[ 0x1fc / 4 ] != 'ATIU')
275: propSize = 0;
276: }
277:
278: if( propSize) {
279: pef = (IOLogicalAddress) IOMalloc( propSize );
280: bcopy( (void *) patch, (void *) pef, propSize );
281: }
282: }
283:
284: if( !pef && (0 == strcmp( regEntry->getName(), "control")) ) {
285:
286: #define ins(i,d,a,simm) ((i<<26)+(d<<21)+(a<<16)+simm)
287: int * patch;
288:
289: patch = (int *) 0xffe6bd50;
290: propSize = 0xac10;
291:
292: // Check control PEF exists there
293: if( patch[ 0x41ac / 4 ] == ins( 32, 3, 0, 0x544)) { // lwz r3,0x544(0)
294:
295: pef = (IOLogicalAddress) IOMalloc( propSize );
296: bcopy( (void *) patch, (void *) pef, propSize );
297: patch = (int *) pef;
298: // patch out low mem accesses
299: patch[ 0x8680 / 4 ] = ins( 14, 12, 0, 0); // addi r12,0,0x0
300: patch[ 0x41ac / 4 ] = ins( 14, 3, 0, 0x544); // addi r3,0,0x544;
301: patch[ 0x8fa0 / 4 ] = ins( 14, 3, 0, 0x648); // addi r3,0,0x648;
302: }
303: }
304: #endif
305:
306: if( pef) {
307: kprintf( "pef = %08x, %08x\n", pef, propSize );
308: inst = IONDRV::instantiate( pef, propSize );
309: if( inst )
310: regEntry->setProperty( "AAPL,ndrvInst", inst);
311:
312: } else
313: inst = 0;
314:
315: return( inst );
316: }
317:
318: const char * IONDRV::driverName( void )
319: {
320: return( (const char *) theDriverDesc->driverOSRuntimeInfo.driverName);
321: }
322:
323:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.