2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
23 * Copyright (c) 1997 Apple Computer, Inc.
28 * sdouglas 22 Oct 97 - first checked in.
29 * sdouglas 21 Jul 98 - start IOKit
30 * sdouglas 14 Dec 98 - start cpp.
35 #include <IOKit/IOLib.h>
36 #include <libkern/c++/OSContainers.h>
39 #include <pexpert/pexpert.h>
43 #include "IOPEFLoader.h"
45 #define LOG if(1) kprintf
47 #define USE_TREE_NDRVS 1
48 #define USE_ROM_NDRVS 1
51 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
53 #define super OSObject
55 OSDefineMetaClassAndStructors(IONDRV
, OSObject
)
57 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
59 IONDRV
* IONDRV::instantiate( IORegistryEntry
* regEntry
,
60 IOLogicalAddress container
,
61 IOByteCount containerSize
,
62 IONDRVUndefinedSymbolHandler undefHandler
,
71 if( false == inst
->init())
74 err
= PCodeOpen( (void *)container
, containerSize
, &inst
->pcInst
);
78 err
= PCodeInstantiate( inst
->pcInst
, undefHandler
, self
);
82 inst
->getSymbol( "DoDriverIO",
83 (IOLogicalAddress
*) &inst
->fDoDriverIO
);
84 if( kIOReturnSuccess
== inst
->getSymbol( "TheDriverDescription",
85 (IOLogicalAddress
*) &inst
->theDriverDesc
)) {
90 name
= (char *) inst
->theDriverDesc
->driverOSRuntimeInfo
.driverName
;
92 strncpy( name
, name
+ 1, plen
);
95 kprintf("ndrv version %08x\n",
96 inst
->theDriverDesc
-> driverType
.version
);
109 void IONDRV::free( void )
112 PCodeClose( pcInst
);
116 IOReturn
IONDRV::getSymbol( const char * symbolName
,
117 IOLogicalAddress
* address
)
121 err
= PCodeFindExport( pcInst
, symbolName
,
122 (LogicalAddress
*)address
, NULL
);
130 if( (err
= NDRVGetShimClass( ioDevice
, instance
, 0, classNames
))
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
) ];
137 OSStatus
NDRVGetShimClass( id ioDevice
, NDRVInstance instance
, UInt32 serviceIndex
, char * className
)
139 NDRVInstanceVars
* ndrvInst
= (NDRVInstanceVars
*) instance
;
141 static const char * driverDescProperty
= "TheDriverDescription";
142 static const char * frameBufferShim
= "IONDRVFramebuffer";
143 DriverDescription
* desc
;
148 err
= PCodeFindExport( ndrvInst
->pcInst
, driverDescProperty
, (IOLogicalAddress
*)&desc
, NULL
);
151 if( desc
->driverDescSignature
!= kTheDescriptionSignature
) {
155 if( serviceIndex
>= desc
->driverServices
.nServices
) {
160 serviceType
= desc
->driverServices
.service
[ serviceIndex
].serviceType
;
161 switch( desc
->driverServices
.service
[ serviceIndex
].serviceCategory
) {
163 case kServiceCategoryNdrvDriver
:
164 if( serviceType
== kNdrvTypeIsVideo
) {
165 strcpy( className
, frameBufferShim
);
179 IOReturn
IONDRV::doDriverIO( UInt32 commandID
, void * contents
,
180 UInt32 commandCode
, UInt32 commandKind
)
184 if( 0 == fDoDriverIO
)
185 return( kIOReturnUnsupported
);
187 err
= CallTVector( /*AddressSpaceID*/ 0, (void *)commandID
, contents
,
188 (void *)commandCode
, (void *)commandKind
, /*p6*/ 0,
194 static const char * commands
[] =
195 { "kOpenCommand", "kCloseCommand",
196 "kReadCommand", "kWriteCommand",
197 "kControlCommand", "kStatusCommand", "kKillIOCommand",
198 "kInitializeCommand", "kFinalizeCommand",
199 "kReplaceCommand", "kSupersededCommand" };
201 LOG("Driver failed (%d) on %s : ", err
, commands
[ commandCode
] );
203 switch( commandCode
) {
204 case kControlCommand
:
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
] );
220 IONDRV
* IONDRV::fromRegistryEntry( IORegistryEntry
* regEntry
,
221 IONDRVUndefinedSymbolHandler handler
,
224 IOLogicalAddress pef
= 0;
225 IOByteCount propSize
= 0;
229 inst
= (IONDRV
*) regEntry
->getProperty("AAPL,ndrvInst");
235 prop
= (OSData
*) regEntry
->getProperty( "driver,AAPL,MacOS,PowerPC" );
236 if( USE_TREE_NDRVS
&& prop
) {
237 pef
= (IOLogicalAddress
) prop
->getBytesNoCopy();
238 propSize
= prop
->getLength();
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.
246 if( !pef
&& (0 == strcmp( regEntry
->getName(), "ATY,mach64_3DU")) ) {
250 patch
= (int *) 0xffe88140;
253 // Check ati PEF exists there
254 if( patch
[ 0x1f0 / 4 ] == 'ATIU') {
256 pef
= (IOLogicalAddress
) IOMalloc( propSize
);
257 bcopy( (void *) patch
, (void *) pef
, propSize
);
261 if( !pef
&& (0 == strcmp( regEntry
->getName(), "ATY,mach64_3DUPro")) ) {
265 patch
= (int *) 0xffe99510;
267 // Check ati PEF exists there
268 if( patch
[ 0x1fc / 4 ] != 'ATIU') {
271 patch
= (int *) 0xffe99550;
273 if( patch
[ 0x1fc / 4 ] != 'ATIU')
278 pef
= (IOLogicalAddress
) IOMalloc( propSize
);
279 bcopy( (void *) patch
, (void *) pef
, propSize
);
283 if( !pef
&& (0 == strcmp( regEntry
->getName(), "control")) ) {
285 #define ins(i,d,a,simm) ((i<<26)+(d<<21)+(a<<16)+simm)
288 patch
= (int *) 0xffe6bd50;
291 // Check control PEF exists there
292 if( patch
[ 0x41ac / 4 ] == ins( 32, 3, 0, 0x544)) { // lwz r3,0x544(0)
294 pef
= (IOLogicalAddress
) IOMalloc( propSize
);
295 bcopy( (void *) patch
, (void *) pef
, propSize
);
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;
306 kprintf( "pef = %08x, %08x\n", pef
, propSize
);
307 inst
= IONDRV::instantiate( regEntry
, pef
, propSize
, handler
, self
);
309 regEntry
->setProperty( "AAPL,ndrvInst", inst
);
317 const char * IONDRV::driverName( void )
319 return( (const char *) theDriverDesc
->driverOSRuntimeInfo
.driverName
);