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 300