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