]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/platform/drvAppleMacIO/AppleMacIO.cpp
5010a52e31e7667d0365d520c3bfd4b45f9773aa
[apple/xnu.git] / iokit / Drivers / platform / drvAppleMacIO / AppleMacIO.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 /*
31 * Copyright (c) 1998 Apple Computer, Inc. All rights reserved.
32 *
33 * HISTORY
34 * 23 Nov 98 sdouglas created.
35 */
36
37 #include <IOKit/system.h>
38 extern "C" {
39 #include <pexpert/pexpert.h>
40 }
41
42 #include <libkern/c++/OSContainers.h>
43 #include <IOKit/IOLib.h>
44 #include <IOKit/IODeviceTreeSupport.h>
45 #include <IOKit/IODeviceMemory.h>
46 #include <IOKit/IOPlatformExpert.h>
47
48 #include <IOKit/pci/IOPCIDevice.h>
49
50 #include <IOKit/platform/AppleMacIO.h>
51
52 #include <IOKit/ppc/IODBDMA.h>
53
54 #include <IOKit/assert.h>
55
56 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
57
58 #define super IOService
59
60 OSDefineMetaClassAndAbstractStructors(AppleMacIO, IOService);
61 OSMetaClassDefineReservedUnused(AppleMacIO, 0);
62 OSMetaClassDefineReservedUnused(AppleMacIO, 1);
63 OSMetaClassDefineReservedUnused(AppleMacIO, 2);
64 OSMetaClassDefineReservedUnused(AppleMacIO, 3);
65
66 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
67
68 bool AppleMacIO::start( IOService * provider )
69 {
70 IOPCIDevice *pciNub = (IOPCIDevice *)provider;
71
72 if( !super::start( provider))
73 return( false);
74
75 // Make sure memory space is on.
76 pciNub->setMemoryEnable(true);
77
78 fNub = provider;
79 fMemory = provider->mapDeviceMemoryWithIndex( 0 );
80 if( 0 == fMemory)
81 IOLog("%s: unexpected ranges\n", getName());
82 else if( !selfTest())
83 IOLog("Warning: AppleMacIO self test fails\n");
84 PMinit(); // initialize for power management
85 temporaryPowerClampOn(); // hold power on till we get children
86 return( true);
87 }
88
89
90 IOService * AppleMacIO::createNub( IORegistryEntry * from )
91 {
92 IOService * nub;
93
94 nub = new AppleMacIODevice;
95
96 if( nub && !nub->init( from, gIODTPlane )) {
97 nub->free();
98 nub = 0;
99 }
100
101 return( nub);
102 }
103
104 void AppleMacIO::processNub(IOService * /*nub*/)
105 {
106 }
107
108 const char * AppleMacIO::deleteList ( void )
109 {
110 return( "('sd', 'st', 'disk', 'tape', 'pram', 'rtc', 'mouse')" );
111 }
112
113 const char * AppleMacIO::excludeList( void )
114 {
115 return( 0 );
116 }
117
118 void AppleMacIO::publishBelow( IORegistryEntry * root )
119 {
120 OSCollectionIterator * kids;
121 IORegistryEntry * next;
122 IOService * nub;
123
124 // infanticide
125 kids = IODTFindMatchingEntries( root, kIODTRecursive, deleteList() );
126 if( kids) {
127 while( (next = (IORegistryEntry *)kids->getNextObject())) {
128 next->detachAll( gIODTPlane);
129 }
130 kids->release();
131 }
132
133 // publish everything below, minus excludeList
134 kids = IODTFindMatchingEntries( root, kIODTRecursive | kIODTExclusive,
135 excludeList());
136 if( kids) {
137 while( (next = (IORegistryEntry *)kids->getNextObject())) {
138
139 if( 0 == (nub = createNub( next )))
140 continue;
141
142 nub->attach( this );
143
144 processNub(nub);
145
146 nub->registerService();
147 }
148 kids->release();
149 }
150 }
151
152 bool AppleMacIO::compareNubName( const IOService * nub,
153 OSString * name, OSString ** matched ) const
154 {
155 return( IODTCompareNubName( nub, name, matched )
156 || nub->IORegistryEntry::compareName( name, matched ) );
157 }
158
159 IOReturn AppleMacIO::getNubResources( IOService * nub )
160 {
161 if( nub->getDeviceMemory())
162 return( kIOReturnSuccess );
163
164 IODTResolveAddressing( nub, "reg", fNub->getDeviceMemoryWithIndex(0) );
165
166 return( kIOReturnSuccess);
167 }
168
169 bool AppleMacIO::selfTest( void )
170 {
171 IODBDMADescriptor *dmaDescriptors;
172 UInt32 dmaDescriptorsPhys;
173 UInt32 i;
174 UInt32 status;
175 IODBDMADescriptor *dmaDesc;
176 volatile IODBDMAChannelRegisters *ioBaseDMA;
177 bool ok = false;
178 enum { kTestChannel = 0x8000 };
179
180 ioBaseDMA = (volatile IODBDMAChannelRegisters *)
181 (((UInt32)fMemory->getVirtualAddress())
182 + kTestChannel );
183
184 do {
185 dmaDescriptors = (IODBDMADescriptor *)IOMallocContiguous(page_size, 1, & dmaDescriptorsPhys);
186 if (!dmaDescriptors)
187 continue;
188
189 if ( (UInt32)dmaDescriptors & (page_size - 1) ) {
190 IOLog("AppleMacIO::%s() - DMA Descriptor memory not page aligned!!", __FUNCTION__);
191 continue;
192 }
193
194 bzero( dmaDescriptors, page_size );
195
196 IODBDMAReset( ioBaseDMA );
197
198 dmaDesc = dmaDescriptors;
199
200 IOMakeDBDMADescriptor( dmaDesc,
201 kdbdmaNop,
202 kdbdmaKeyStream0,
203 kdbdmaIntNever,
204 kdbdmaBranchNever,
205 kdbdmaWaitNever,
206 0,
207 0 );
208
209 dmaDesc++;
210
211 IOMakeDBDMADescriptorDep( dmaDesc,
212 kdbdmaStoreQuad,
213 kdbdmaKeySystem,
214 kdbdmaIntNever,
215 kdbdmaBranchNever,
216 kdbdmaWaitNever,
217 4,
218 dmaDescriptorsPhys+16*sizeof(IODBDMADescriptor),
219 0x12345678 );
220
221 dmaDesc++;
222
223 IOMakeDBDMADescriptor( dmaDesc,
224 kdbdmaStop,
225 kdbdmaKeyStream0,
226 kdbdmaIntNever,
227 kdbdmaBranchNever,
228 kdbdmaWaitNever,
229 0,
230 0 );
231
232
233 for ( i = 0; (!ok) && (i < 3); i++ )
234 {
235 dmaDescriptors[16].operation = 0;
236
237 IOSetDBDMACommandPtr( ioBaseDMA, dmaDescriptorsPhys );
238 IODBDMAContinue( ioBaseDMA );
239
240 IODelay( 200 );
241
242 status = IOGetDBDMAChannelStatus( ioBaseDMA );
243
244 if ( ((status & kdbdmaActive) == 0)
245 && ((status & kdbdmaDead) == 0)
246 && (OSReadSwapInt32( &dmaDescriptors[16].operation, 0 ) == 0x12345678 ))
247 ok = true;
248 }
249
250 IODBDMAReset( ioBaseDMA );
251
252 } while (false);
253
254 if (dmaDescriptors)
255 IOFreeContiguous(dmaDescriptors, page_size);
256
257
258 return ok;
259 }
260
261 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
262
263 #undef super
264 #define super IOService
265
266 OSDefineMetaClassAndStructors(AppleMacIODevice, IOService);
267 OSMetaClassDefineReservedUnused(AppleMacIODevice, 0);
268 OSMetaClassDefineReservedUnused(AppleMacIODevice, 1);
269 OSMetaClassDefineReservedUnused(AppleMacIODevice, 2);
270 OSMetaClassDefineReservedUnused(AppleMacIODevice, 3);
271
272 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
273
274 bool AppleMacIODevice::compareName( OSString * name,
275 OSString ** matched ) const
276 {
277 return (IODTCompareNubName(this, name, matched) ||
278 IORegistryEntry::compareName(name, matched));
279 }
280
281 IOService * AppleMacIODevice::matchLocation( IOService * /* client */ )
282 {
283 return this;
284 }
285
286 IOReturn AppleMacIODevice::getResources( void )
287 {
288 IOService *macIO = this;
289
290 if (getDeviceMemory() != 0) return kIOReturnSuccess;
291
292 while (macIO && ((macIO = macIO->getProvider()) != 0))
293 if (strcmp("mac-io", macIO->getName()) == 0) break;
294
295 if (macIO == 0) return kIOReturnError;
296
297 IODTResolveAddressing(this, "reg", macIO->getDeviceMemoryWithIndex(0));
298
299 return kIOReturnSuccess;
300 }
301