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