|
|
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:
36: #import <driverkit/ppc/IOTreeDevice.h>
37: #import "IOPEFLoader.h"
38: #import "IONDRVInterface.h"
39:
40: #define LOG if(1) kprintf
41:
42: struct NDRVInstanceVars {
43: PCodeInstance pcInst;
44: };
45: typedef struct NDRVInstanceVars NDRVInstanceVars;
46:
47:
48: OSStatus NDRVLoad( LogicalAddress container, ByteCount containerSize, NDRVInstance * instance )
49: {
50: NDRVInstanceVars * ndrvInst;
51: OSStatus err;
52:
53: ndrvInst = (NDRVInstanceVars *) IOMalloc( sizeof( NDRVInstanceVars));
54:
55: err = PCodeOpen( container, containerSize, &ndrvInst->pcInst );
56:
57: if( err == noErr)
58: err = PCodeInstantiate( ndrvInst->pcInst );
59:
60: *instance = ndrvInst;
61:
62: return( err);
63: }
64:
65: OSStatus NDRVGetSymbol( NDRVInstance instance, const char * symbolName, LogicalAddress * address )
66: {
67: NDRVInstanceVars * ndrvInst = (NDRVInstanceVars *) instance;
68: OSStatus err;
69:
70: err = PCodeFindExport( ndrvInst->pcInst, symbolName, address, NULL );
71: return( err);
72: }
73:
74: OSStatus NDRVGetShimClass( id ioDevice, NDRVInstance instance, UInt32 serviceIndex, char * className )
75: {
76: NDRVInstanceVars * ndrvInst = (NDRVInstanceVars *) instance;
77: OSStatus err;
78: static const char * driverDescProperty = "TheDriverDescription";
79: static const char * frameBufferShim = "IONDRVFramebuffer";
80: DriverDescription * desc;
81: UInt32 serviceType;
82:
83: className[ 0 ] = 0;
84: do {
85: err = PCodeFindExport( ndrvInst->pcInst, driverDescProperty, (LogicalAddress *)&desc, NULL );
86: if( err) continue;
87:
88: if( desc->driverDescSignature != kTheDescriptionSignature) {
89: err = -1;
90: continue;
91: }
92: if( serviceIndex >= desc->driverServices.nServices) {
93: err = -1;
94: continue;
95: }
96:
97: serviceType = desc->driverServices.service[ serviceIndex ].serviceType;
98: switch( desc->driverServices.service[ serviceIndex ].serviceCategory) {
99:
100: case kServiceCategoryNdrvDriver:
101: if( serviceType == kNdrvTypeIsVideo) {
102: strcpy( className, frameBufferShim);
103: break;
104: }
105: default:
106: err = -1;
107: }
108: } while( false);
109:
110: return( err);
111: }
112:
113: OSStatus NDRVUnload( NDRVInstance * instance )
114: {
115: return( noErr);
116: }
117:
118:
119: OSStatus NDRVDoDriverIO( LogicalAddress entry,
120: UInt32 commandID, void * contents, UInt32 commandCode, UInt32 commandKind )
121: {
122: OSStatus err;
123:
124: #if 1
125:
126: fpu_save_thread();
127: err = CallTVector( /*AddressSpaceID*/ 0, (void *)commandID, contents,
128: (void *)commandCode, (void *)commandKind, /*p6*/ 0, entry );
129: fpu_disable_thread();
130:
131: #else
132:
133: static LogicalAddress stack = NULL; // FIXME
134:
135: if( stack == NULL)
136: stack = (LogicalAddress) ( IOMalloc( 32768) + 32768 );
137:
138: fpu_save();
139: err = CallTVectorWithStack( /*AddressSpaceID*/ 0, (void *)commandID, contents,
140: (void *)commandCode, (void *)commandKind, /*p6*/ 0, entry, stack);
141: fpu_disable();
142:
143: #endif
144:
145: #if 0
146: if( err) {
147: UInt32 i;
148: static const char * commands[] =
149: { "kOpenCommand", "kCloseCommand", "kReadCommand", "kWriteCommand",
150: "kControlCommand", "kStatusCommand", "kKillIOCommand", "kInitializeCommand",
151: "kFinalizeCommand", "kReplaceCommand", "kSupersededCommand" };
152:
153: LOG("Driver failed (%d) on %s : ", err, commands[ commandCode ] );
154:
155: switch( commandCode) {
156: case kControlCommand:
157: case kStatusCommand:
158: LOG("%d : ", ((UInt16 *)contents)[ 0x1a / 2 ]);
159: contents = ((void **)contents)[ 0x1c / 4 ];
160: for( i = 0; i<5; i++ )
161: LOG("%08x, ", ((UInt32 *)contents)[i] );
162: break;
163: }
164: LOG("\n");
165: }
166: #endif
167:
168: return( err);
169: }
170:
171: // autoconf_ppc comes here for matching
172: BOOL
173: NDRVForDevice( IOTreeDevice * ioDevice )
174: {
175: OSStatus err;
176: NDRVInstance instance;
177: LogicalAddress pef;
178: IOByteCount propSize;
179: static const char * pefPropertyName = "driver,AAPL,MacOS,PowerPC";
180: IOPropertyTable * propTable = [ioDevice propertyTable];
181: char classNames[ 80 ];
182:
183:
184: if( NO == [ioDevice isKindOf:[IOTreeDevice class]] )
185: return( NO);
186:
187: #if 0
188: // to test code aligning
189: err = [propTable getProperty:pefPropertyName flags:kReferenceProperty
190: value:nil length:&propSize];
191: if( err == noErr) {
192: pef = IOMalloc( propSize);
193: err = [propTable getProperty:pefPropertyName flags:0
194: value:&pef length:&propSize];
195: }
196: #else
197: err = [propTable getProperty:pefPropertyName flags:kReferenceProperty
198: value:&pef length:&propSize];
199: #endif
200:
201: // God awful hack:
202: // Some onboard devices don't have the ndrv in the tree. The new booter
203: // can load & match PEF's but only from disk, not network boots.
204:
205: if( err && (strcmp( [ioDevice nodeName], "ATY,mach64_3DU") == 0) ) {
206:
207: unsigned int * patch;
208:
209: patch = (unsigned int *) 0xffe88140;
210: propSize = 0x10a80;
211:
212: // Check ati PEF exists there
213: if( patch[ 0x1f0 / 4 ] == 'ATIU') {
214:
215: pef = (LogicalAddress) IOMalloc( propSize );
216: bcopy( (void *) patch, pef, propSize );
217: err = noErr;
218: }
219: }
220:
221: if( err && (strcmp( [ioDevice nodeName], "ATY,mach64_3DUPro") == 0) ) {
222:
223: unsigned int * patch;
224:
225: patch = (unsigned int *) 0xffe99510;
226: propSize = 0x12008;
227:
228: // Check ati PEF exists there
229: if( patch[ 0x1fc / 4 ] == 'ATIU') {
230:
231: pef = (LogicalAddress) IOMalloc( propSize );
232: bcopy( (void *) patch, pef, propSize );
233: err = noErr;
234: }
235: }
236:
237: if( err && (strcmp( [ioDevice nodeName], "control") == 0) ) {
238:
239: #define ins(i,d,a,simm) ((i<<26)+(d<<21)+(a<<16)+simm)
240: unsigned int * patch;
241:
242: patch = (unsigned int *) 0xffe6bd50;
243: propSize = 0xac10;
244:
245: // Check control PEF exists there
246: if( patch[ 0x41ac / 4 ] == ins( 32, 3, 0, 0x544)) { // lwz r3,0x544(0)
247:
248: pef = (LogicalAddress) IOMalloc( propSize );
249: bcopy( (void *) patch, pef, propSize );
250: patch = (unsigned int *) pef;
251: // patch out low mem accesses
252: patch[ 0x8680 / 4 ] = ins( 14, 12, 0, 0); // addi r12,0,0x0
253: patch[ 0x41ac / 4 ] = ins( 14, 3, 0, 0x544); // addi r3,0,0x544;
254: patch[ 0x8fa0 / 4 ] = ins( 14, 3, 0, 0x648); // addi r3,0,0x648;
255: err = noErr;
256: }
257: }
258:
259: if( err == noErr) {
260: do {
261: if( (err = NDRVLoad( pef, propSize, &instance ))
262: ) continue;
263: [propTable createProperty:"AAPL,ndrvInst" flags:0
264: value:&instance length:sizeof( NDRVInstance)];
265: if( (err = NDRVGetShimClass( ioDevice, instance, 0, classNames ))
266: ) continue;
267:
268: err = [propTable createProperty:"AAPL,dk_Driver Name" flags:0
269: value:classNames length:strlen( classNames) ];
270: err = [propTable createProperty:"AAPL,dk_Server Name" flags:0
271: value:classNames length:strlen( classNames) ];
272:
273: return( YES);
274:
275: } while( false);
276: }
277:
278: return( NO);
279: }
280:
281:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.