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