]> git.saurik.com Git - apple/xnu.git/blob - iokit/Families/IONDRVSupport/IONDRV.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Families / IONDRVSupport / IONDRV.cpp
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( IORegistryEntry * regEntry,
60 IOLogicalAddress container,
61 IOByteCount containerSize,
62 IONDRVUndefinedSymbolHandler undefHandler,
63 void * self )
64 {
65 OSStatus err = 1;
66 IONDRV * inst;
67
68 inst = new IONDRV;
69
70 if( inst) do {
71 if( false == inst->init())
72 continue;
73
74 err = PCodeOpen( (void *)container, containerSize, &inst->pcInst );
75 if( err)
76 continue;
77
78 err = PCodeInstantiate( inst->pcInst, undefHandler, self );
79 if( err)
80 continue;
81
82 inst->getSymbol( "DoDriverIO",
83 (IOLogicalAddress *) &inst->fDoDriverIO );
84 if( kIOReturnSuccess == inst->getSymbol( "TheDriverDescription",
85 (IOLogicalAddress *) &inst->theDriverDesc )) {
86
87 char * name;
88 int plen;
89
90 name = (char *) inst->theDriverDesc->driverOSRuntimeInfo.driverName;
91 plen = name[ 0 ];
92 strncpy( name, name + 1, plen);
93 name[ plen ] = 0;
94
95 kprintf("ndrv version %08x\n",
96 inst->theDriverDesc-> driverType.version);
97 }
98
99 } while( false);
100
101 if( inst && err) {
102 inst->release();
103 inst = 0;
104 }
105
106 return( inst );
107 }
108
109 void IONDRV::free( void )
110 {
111 if( pcInst)
112 PCodeClose( pcInst );
113 super::free();
114 }
115
116 IOReturn IONDRV::getSymbol( const char * symbolName,
117 IOLogicalAddress * address )
118 {
119 OSStatus err;
120
121 err = PCodeFindExport( pcInst, symbolName,
122 (LogicalAddress *)address, NULL );
123 if( err)
124 *address = 0;
125
126 return( err);
127 }
128
129 #if 0
130 if( (err = NDRVGetShimClass( ioDevice, instance, 0, classNames ))
131 ) continue;
132 err = [propTable createProperty:"AAPL,dk_Driver Name" flags:0
133 value:classNames length:strlen( classNames) ];
134 err = [propTable createProperty:"AAPL,dk_Server Name" flags:0
135 value:classNames length:strlen( classNames) ];
136
137 OSStatus NDRVGetShimClass( id ioDevice, NDRVInstance instance, UInt32 serviceIndex, char * className )
138 {
139 NDRVInstanceVars * ndrvInst = (NDRVInstanceVars *) instance;
140 OSStatus err;
141 static const char * driverDescProperty = "TheDriverDescription";
142 static const char * frameBufferShim = "IONDRVFramebuffer";
143 DriverDescription * desc;
144 UInt32 serviceType;
145
146 className[ 0 ] = 0;
147 do {
148 err = PCodeFindExport( ndrvInst->pcInst, driverDescProperty, (IOLogicalAddress *)&desc, NULL );
149 if( err) continue;
150
151 if( desc->driverDescSignature != kTheDescriptionSignature) {
152 err = -1;
153 continue;
154 }
155 if( serviceIndex >= desc->driverServices.nServices) {
156 err = -1;
157 continue;
158 }
159
160 serviceType = desc->driverServices.service[ serviceIndex ].serviceType;
161 switch( desc->driverServices.service[ serviceIndex ].serviceCategory) {
162
163 case kServiceCategoryNdrvDriver:
164 if( serviceType == kNdrvTypeIsVideo) {
165 strcpy( className, frameBufferShim);
166 break;
167 }
168 default:
169 err = -1;
170 }
171 } while( false);
172
173 return( err);
174 }
175 #endif
176
177
178
179 IOReturn IONDRV::doDriverIO( UInt32 commandID, void * contents,
180 UInt32 commandCode, UInt32 commandKind )
181 {
182 OSStatus err;
183
184 if( 0 == fDoDriverIO)
185 return( kIOReturnUnsupported );
186
187 err = CallTVector( /*AddressSpaceID*/ 0, (void *)commandID, contents,
188 (void *)commandCode, (void *)commandKind, /*p6*/ 0,
189 fDoDriverIO );
190
191 #if 0
192 if( err) {
193 UInt32 i;
194 static const char * commands[] =
195 { "kOpenCommand", "kCloseCommand",
196 "kReadCommand", "kWriteCommand",
197 "kControlCommand", "kStatusCommand", "kKillIOCommand",
198 "kInitializeCommand", "kFinalizeCommand",
199 "kReplaceCommand", "kSupersededCommand" };
200
201 LOG("Driver failed (%d) on %s : ", err, commands[ commandCode ] );
202
203 switch( commandCode) {
204 case kControlCommand:
205 case kStatusCommand:
206 LOG("%d : ", ((UInt16 *)contents)[ 0x1a / 2 ]);
207 contents = ((void **)contents)[ 0x1c / 4 ];
208 for( i = 0; i<5; i++ )
209 LOG("%08x, ", ((UInt32 *)contents)[i] );
210 break;
211 }
212 LOG("\n");
213 }
214 #endif
215
216 return( err);
217 }
218
219
220 IONDRV * IONDRV::fromRegistryEntry( IORegistryEntry * regEntry,
221 IONDRVUndefinedSymbolHandler handler,
222 void * self )
223 {
224 IOLogicalAddress pef = 0;
225 IOByteCount propSize = 0;
226 OSData * prop;
227 IONDRV * inst;
228
229 inst = (IONDRV *) regEntry->getProperty("AAPL,ndrvInst");
230 if( inst) {
231 inst->retain();
232 return( inst );
233 }
234
235 prop = (OSData *) regEntry->getProperty( "driver,AAPL,MacOS,PowerPC" );
236 if( USE_TREE_NDRVS && prop) {
237 pef = (IOLogicalAddress) prop->getBytesNoCopy();
238 propSize = prop->getLength();
239 }
240
241 // God awful hack:
242 // Some onboard devices don't have the ndrv in the tree. The booter
243 // can load & match PEF's but only from disk, not network boots.
244
245 #if USE_ROM_NDRVS
246 if( !pef && (0 == strcmp( regEntry->getName(), "ATY,mach64_3DU")) ) {
247
248 int * patch;
249
250 patch = (int *) 0xffe88140;
251 propSize = 0x10a80;
252
253 // Check ati PEF exists there
254 if( patch[ 0x1f0 / 4 ] == 'ATIU') {
255
256 pef = (IOLogicalAddress) IOMalloc( propSize );
257 bcopy( (void *) patch, (void *) pef, propSize );
258 }
259 }
260
261 if( !pef && (0 == strcmp( regEntry->getName(), "ATY,mach64_3DUPro")) ) {
262
263 int * patch;
264
265 patch = (int *) 0xffe99510;
266 propSize = 0x12008;
267 // Check ati PEF exists there
268 if( patch[ 0x1fc / 4 ] != 'ATIU') {
269
270 // silk version
271 patch = (int *) 0xffe99550;
272 propSize = 0x12058;
273 if( patch[ 0x1fc / 4 ] != 'ATIU')
274 propSize = 0;
275 }
276
277 if( propSize) {
278 pef = (IOLogicalAddress) IOMalloc( propSize );
279 bcopy( (void *) patch, (void *) pef, propSize );
280 }
281 }
282
283 if( !pef && (0 == strcmp( regEntry->getName(), "control")) ) {
284
285 #define ins(i,d,a,simm) ((i<<26)+(d<<21)+(a<<16)+simm)
286 int * patch;
287
288 patch = (int *) 0xffe6bd50;
289 propSize = 0xac10;
290
291 // Check control PEF exists there
292 if( patch[ 0x41ac / 4 ] == ins( 32, 3, 0, 0x544)) { // lwz r3,0x544(0)
293
294 pef = (IOLogicalAddress) IOMalloc( propSize );
295 bcopy( (void *) patch, (void *) pef, propSize );
296 patch = (int *) pef;
297 // patch out low mem accesses
298 patch[ 0x8680 / 4 ] = ins( 14, 12, 0, 0); // addi r12,0,0x0
299 patch[ 0x41ac / 4 ] = ins( 14, 3, 0, 0x544); // addi r3,0,0x544;
300 patch[ 0x8fa0 / 4 ] = ins( 14, 3, 0, 0x648); // addi r3,0,0x648;
301 }
302 }
303 #endif
304
305 if( pef) {
306 kprintf( "pef = %08x, %08x\n", pef, propSize );
307 inst = IONDRV::instantiate( regEntry, pef, propSize, handler, self );
308 if( inst )
309 regEntry->setProperty( "AAPL,ndrvInst", inst);
310
311 } else
312 inst = 0;
313
314 return( inst );
315 }
316
317 const char * IONDRV::driverName( void )
318 {
319 return( (const char *) theDriverDesc->driverOSRuntimeInfo.driverName);
320 }
321
322