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