1/* 2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 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. 11 * 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 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 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. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22/* 23 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. 24 * 25 * HISTORY 26 * 27 */ 28 29 30#ifndef _IOKIT_IOPCIBRIDGE_H 31#define _IOKIT_IOPCIBRIDGE_H 32 33#include <IOKit/IOService.h> 34#include <IOKit/IODeviceMemory.h> 35#include <IOKit/IOFilterInterruptEventSource.h> 36#include <IOKit/pwr_mgt/RootDomain.h> 37#include <IOKit/pci/IOAGPDevice.h> 38 39/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 40class IOPCIConfigurator; 41class IOPCIDevice; 42class IOPCIMessagedInterruptController; 43 44enum { 45 kIOPCIResourceTypeMemory = 0, 46 kIOPCIResourceTypePrefetchMemory = 1, 47 kIOPCIResourceTypeIO = 2, 48 kIOPCIResourceTypeBusNumber = 3, 49 kIOPCIResourceTypeCount = 4, 50}; 51 52/*! 53 @class IOPCIBridge 54 @abstract Base class for all PCI bridge drivers. 55*/ 56 57class IOPCIBridge : public IOService 58{ 59 friend class IOPCIDevice; 60 friend class IOPCI2PCIBridge; 61 friend class IOPCIConfigurator; 62 63 OSDeclareAbstractStructors(IOPCIBridge) 64 65private: 66 static void initialize(void); 67 IORegistryEntry * findMatching( OSIterator * in, IOPCIAddressSpace space ); 68 virtual bool isDTNub( IOPCIDevice * nub ); 69 bool checkProperties( IOPCIDevice * entry ); 70 71 void removeDevice( IOPCIDevice * device, IOOptionBits options = 0 ); 72 73 void restoreQEnter(IOPCIDevice * device); 74 void restoreQRemove(IOPCIDevice * device); 75 76 IOReturn restoreTunnelState(IOPCIDevice * root, IOOptionBits options); 77 IOReturn restoreMachineState( IOOptionBits options, IOPCIDevice * device ); 78 void tunnelsWait(IOPCIDevice * device); 79 80 IOReturn _restoreDeviceState( IOPCIDevice * device, IOOptionBits options ); 81 IOReturn resolveLegacyInterrupts( IOService * provider, IOPCIDevice * nub ); 82 IOReturn resolveMSIInterrupts ( IOService * provider, IOPCIDevice * nub ); 83 84 IOReturn relocate(IOPCIDevice * device, uint32_t options); 85 void spaceFromProperties( IORegistryEntry * regEntry, 86 IOPCIAddressSpace * space ); 87 void updateWakeReason(IOPCIDevice * device); 88 89protected: 90 static void nvLocation( IORegistryEntry * entry, 91 UInt8 * busNum, UInt8 * deviceNum, UInt8 * functionNum ); 92#if !defined(__LP64__) || defined(__x86_64__) 93 static SInt32 compareAddressCell( UInt32 cellCount, UInt32 cleft[], UInt32 cright[] ); 94#else 95 static SInt64 compareAddressCell( UInt32 cellCount, UInt32 cleft[], UInt32 cright[] ); 96#endif 97 IOReturn setDeviceASPMBits(IOPCIDevice * device, uint32_t bits); 98 IOReturn setDeviceL1PMBits(IOPCIDevice * device, uint32_t bits); 99 100 IOReturn setDevicePowerState(IOPCIDevice * device, IOOptionBits options, 101 unsigned long prevState, unsigned long newState); 102 static IOReturn configOp(IOService * device, uintptr_t op, void * result, void * arg = 0); 103 static void deferredProbe(IOPCIDevice * device); 104 105 void * __reserved1; 106 void * __reserved2; 107 108/*! @struct ExpansionData 109 @discussion This structure will be used to expand the capablilties of the IOPCIBridge in the future. 110*/ 111 struct ExpansionData 112 { 113 struct IOPCIRange * rangeLists[kIOPCIResourceTypeCount]; 114 IOPCIMessagedInterruptController *messagedInterruptController; 115 }; 116 117/*! @var reserved 118 Reserved for future use. (Internal use only) 119*/ 120private: 121 ExpansionData *reserved; 122 123protected: 124 IOWorkLoop * getConfiguratorWorkLoop(void) const; 125 126public: 127 static IOPCIEventSource * createEventSource( 128 OSObject * owner, IOPCIEventSource::Action action, uint32_t options); 129 130public: 131 virtual void probeBus( IOService * provider, UInt8 busNum ); 132 133 virtual UInt8 firstBusNum( void ); 134 virtual UInt8 lastBusNum( void ); 135 136 virtual void spaceFromProperties( OSDictionary * propTable, 137 IOPCIAddressSpace * space ); 138 virtual OSDictionary * constructProperties( IOPCIAddressSpace space ); 139 140 virtual IOPCIDevice * createNub( OSDictionary * from ); 141 142 virtual bool initializeNub( IOPCIDevice * nub, OSDictionary * from ); 143 144 virtual bool publishNub( IOPCIDevice * nub, UInt32 index ); 145 146 virtual bool addBridgeMemoryRange( IOPhysicalAddress start, 147 IOPhysicalLength length, bool host ); 148 149 virtual bool addBridgeIORange( IOByteCount start, IOByteCount length ); 150 151 152private: 153 virtual bool constructRange( IOPCIAddressSpace * flags, 154 IOPhysicalAddress64 phys, IOPhysicalLength64 len, 155 OSArray * array ); 156 157 virtual bool matchNubWithPropertyTable( IOService * nub, 158 OSDictionary * propertyTable, 159 SInt32 * score ); 160 161 virtual bool compareNubName( const IOService * nub, OSString * name, 162 OSString ** matched = 0 ) const; 163 164 virtual bool pciMatchNub( IOPCIDevice * nub, 165 OSDictionary * table, SInt32 * score); 166 167 virtual bool matchKeys( IOPCIDevice * nub, const char * keys, 168 UInt32 defaultMask, UInt8 regNum ); 169 170 virtual IOReturn getNubResources( IOService * nub ); 171 172 virtual IOReturn getNubAddressing( IOPCIDevice * nub ); 173 174 virtual IOReturn getDTNubAddressing( IOPCIDevice * nub ); 175 176public: 177 virtual void free( void ); 178 179 virtual bool start( IOService * provider ); 180 181 virtual void stop( IOService * provider ); 182 183 virtual bool configure( IOService * provider ); 184 185 virtual IOReturn setProperties(OSObject * properties); 186 187 virtual IOReturn newUserClient(task_t owningTask, void * securityID, 188 UInt32 type, OSDictionary * properties, 189 IOUserClient ** handler); 190 191 virtual unsigned long maxCapabilityForDomainState ( IOPMPowerFlags domainState ); 192 virtual unsigned long initialPowerStateForDomainState ( IOPMPowerFlags domainState ); 193 virtual unsigned long powerStateForDomainState ( IOPMPowerFlags domainState ); 194 195 virtual IOReturn callPlatformFunction(const OSSymbol * functionName, 196 bool waitForFunction, 197 void * param1, void * param2, 198 void * param3, void * param4); 199 200 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 201 202 virtual IODeviceMemory * ioDeviceMemory( void ) = 0; 203 204 virtual UInt32 configRead32( IOPCIAddressSpace space, UInt8 offset ) = 0; 205 virtual void configWrite32( IOPCIAddressSpace space, 206 UInt8 offset, UInt32 data ) = 0; 207 virtual UInt16 configRead16( IOPCIAddressSpace space, UInt8 offset ) = 0; 208 virtual void configWrite16( IOPCIAddressSpace space, 209 UInt8 offset, UInt16 data ) = 0; 210 virtual UInt8 configRead8( IOPCIAddressSpace space, UInt8 offset ) = 0; 211 virtual void configWrite8( IOPCIAddressSpace space, 212 UInt8 offset, UInt8 data ) = 0; 213 214 virtual IOPCIAddressSpace getBridgeSpace( void ) = 0; 215 216 virtual UInt32 findPCICapability( IOPCIAddressSpace space, 217 UInt8 capabilityID, UInt8 * offset = 0 ); 218 219 virtual IOReturn setDevicePowerState( IOPCIDevice * device, 220 unsigned long whatToDo ); 221 virtual IOReturn saveDeviceState( IOPCIDevice * device, 222 IOOptionBits options = 0 ); 223 virtual IOReturn restoreDeviceState( IOPCIDevice * device, 224 IOOptionBits options = 0 ); 225 226 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 227 228 virtual IOReturn createAGPSpace( IOAGPDevice * master, 229 IOOptionBits options, 230 IOPhysicalAddress * address, 231 IOPhysicalLength * length ); 232 233 virtual IOReturn destroyAGPSpace( IOAGPDevice * master ); 234 235 virtual IORangeAllocator * getAGPRangeAllocator( IOAGPDevice * master ); 236 237 virtual IOOptionBits getAGPStatus( IOAGPDevice * master, 238 IOOptionBits options = 0 ); 239 virtual IOReturn resetAGPDevice( IOAGPDevice * master, 240 IOOptionBits options = 0 ); 241 242 virtual IOReturn getAGPSpace( IOAGPDevice * master, 243 IOPhysicalAddress * address, 244 IOPhysicalLength * length ); 245 246 virtual IOReturn commitAGPMemory( IOAGPDevice * master, 247 IOMemoryDescriptor * memory, 248 IOByteCount agpOffset, 249 IOOptionBits options ); 250 251 virtual IOReturn releaseAGPMemory( IOAGPDevice * master, 252 IOMemoryDescriptor * memory, 253 IOByteCount agpOffset, 254 IOOptionBits options ); 255 256protected: 257 OSMetaClassDeclareReservedUsed(IOPCIBridge, 0); 258private: 259 virtual bool addBridgePrefetchableMemoryRange( IOPhysicalAddress start, 260 IOPhysicalLength length, 261 bool host ); 262protected: 263 bool addBridgePrefetchableMemoryRange( addr64_t start, addr64_t length ); 264 IOReturn kernelRequestProbe(IOPCIDevice * device, uint32_t options); 265 IOReturn protectDevice(IOPCIDevice * device, uint32_t space, uint32_t prot); 266 267 OSMetaClassDeclareReservedUsed(IOPCIBridge, 1); 268 virtual UInt32 extendedFindPCICapability( IOPCIAddressSpace space, 269 UInt32 capabilityID, IOByteCount * offset = 0 ); 270 271 OSMetaClassDeclareReservedUsed(IOPCIBridge, 2); 272 virtual IOReturn setDeviceASPMState(IOPCIDevice * device, 273 IOService * client, IOOptionBits state); 274 275 OSMetaClassDeclareReservedUsed(IOPCIBridge, 3); 276 virtual IOReturn checkLink(uint32_t options = 0); 277 278 OSMetaClassDeclareReservedUsed(IOPCIBridge, 4); 279 virtual IOReturn enableLTR(IOPCIDevice * device, bool enable); 280 281 OSMetaClassDeclareReservedUsed(IOPCIBridge, 5); 282 virtual IOPCIEventSource * createEventSource(IOPCIDevice * device, 283 OSObject * owner, IOPCIEventSource::Action action, uint32_t options); 284 285 // Unused Padding 286 OSMetaClassDeclareReservedUnused(IOPCIBridge, 6); 287 OSMetaClassDeclareReservedUnused(IOPCIBridge, 7); 288 OSMetaClassDeclareReservedUnused(IOPCIBridge, 8); 289 OSMetaClassDeclareReservedUnused(IOPCIBridge, 9); 290 OSMetaClassDeclareReservedUnused(IOPCIBridge, 10); 291 OSMetaClassDeclareReservedUnused(IOPCIBridge, 11); 292 OSMetaClassDeclareReservedUnused(IOPCIBridge, 12); 293 OSMetaClassDeclareReservedUnused(IOPCIBridge, 13); 294 OSMetaClassDeclareReservedUnused(IOPCIBridge, 14); 295 OSMetaClassDeclareReservedUnused(IOPCIBridge, 15); 296 OSMetaClassDeclareReservedUnused(IOPCIBridge, 16); 297 OSMetaClassDeclareReservedUnused(IOPCIBridge, 17); 298 OSMetaClassDeclareReservedUnused(IOPCIBridge, 18); 299 OSMetaClassDeclareReservedUnused(IOPCIBridge, 19); 300 OSMetaClassDeclareReservedUnused(IOPCIBridge, 20); 301 OSMetaClassDeclareReservedUnused(IOPCIBridge, 21); 302 OSMetaClassDeclareReservedUnused(IOPCIBridge, 22); 303 OSMetaClassDeclareReservedUnused(IOPCIBridge, 23); 304 OSMetaClassDeclareReservedUnused(IOPCIBridge, 24); 305 OSMetaClassDeclareReservedUnused(IOPCIBridge, 25); 306 OSMetaClassDeclareReservedUnused(IOPCIBridge, 26); 307 OSMetaClassDeclareReservedUnused(IOPCIBridge, 27); 308 OSMetaClassDeclareReservedUnused(IOPCIBridge, 28); 309 OSMetaClassDeclareReservedUnused(IOPCIBridge, 29); 310 OSMetaClassDeclareReservedUnused(IOPCIBridge, 30); 311 OSMetaClassDeclareReservedUnused(IOPCIBridge, 31); 312}; 313 314/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 315 316class IOPCI2PCIBridge : public IOPCIBridge 317{ 318 friend class IOPCIEventSource; 319 friend class IOPCIDevice; 320 321 OSDeclareDefaultStructors(IOPCI2PCIBridge) 322 323protected: 324 IOFilterInterruptEventSource * fBridgeInterruptSource; 325 326private: 327 IOPCIDevice * fBridgeDevice; 328 IOTimerEventSource * fTimerProbeES; 329 IOWorkLoop * fWorkLoop; 330 IOPMDriverAssertionID fPMAssertion; 331 IOSimpleLock * fISRLock; 332 struct IOPCIAERRoot * fAERRoot; 333 uint32_t __resvA[6]; 334 int32_t fTunnelL1EnableCount; 335 uint32_t fHotplugCount; 336 337 uint8_t _resvA[3]; 338 uint8_t fHotPlugInts; 339 uint8_t fIntsPending; 340 uint8_t fIsAERRoot; 341 342 uint8_t fPresence; 343 uint8_t fWaitingLinkEnable; 344 uint8_t fLinkChangeOnly; 345 uint8_t fBridgeInterruptEnablePending; 346 uint8_t fNeedProbe; 347 uint8_t fPresenceInt; 348 uint8_t fBridgeMSI; 349 uint8_t fNoDevice; 350 uint8_t fLinkControlWithPM; 351 uint8_t fPowerState; 352 char fLogName[32]; 353; 354 355/*! @struct ExpansionData 356 @discussion This structure will be used to expand the capablilties of the class in the future. 357 */ 358 struct ExpansionData {}; 359 360/*! @var reserved 361 Reserved for future use. (Internal use only) */ 362 ExpansionData *reserved; 363 364public: 365 366 virtual UInt8 firstBusNum( void ); 367 virtual UInt8 lastBusNum( void ); 368 369public: 370 virtual void free(); 371 372 virtual bool serializeProperties( OSSerialize * serialize ) const; 373 374 virtual IOService * probe( IOService * provider, 375 SInt32 * score ); 376 377 virtual bool start( IOService * provider ); 378 379 virtual void stop( IOService * provider ); 380 381 virtual bool configure( IOService * provider ); 382 383 virtual void probeBus( IOService * provider, UInt8 busNum ); 384 385 virtual IOReturn requestProbe( IOOptionBits options ); 386 387 virtual void saveBridgeState( void ); 388 389 virtual void restoreBridgeState( void ); 390 391 IOReturn setPowerState( unsigned long powerState, 392 IOService * whatDevice ); 393 394 void adjustPowerState(unsigned long state); 395 396 virtual IOReturn saveDeviceState( IOPCIDevice * device, 397 IOOptionBits options = 0 ); 398 399 virtual bool publishNub( IOPCIDevice * nub, UInt32 index ); 400 401 virtual IODeviceMemory * ioDeviceMemory( void ); 402 403 virtual IOPCIAddressSpace getBridgeSpace( void ); 404 405 virtual UInt32 configRead32( IOPCIAddressSpace space, UInt8 offset ); 406 virtual void configWrite32( IOPCIAddressSpace space, 407 UInt8 offset, UInt32 data ); 408 virtual UInt16 configRead16( IOPCIAddressSpace space, UInt8 offset ); 409 virtual void configWrite16( IOPCIAddressSpace space, 410 UInt8 offset, UInt16 data ); 411 virtual UInt8 configRead8( IOPCIAddressSpace space, UInt8 offset ); 412 virtual void configWrite8( IOPCIAddressSpace space, 413 UInt8 offset, UInt8 data ); 414 415 virtual IOReturn setDeviceASPMState(IOPCIDevice * device, 416 IOService * client, IOOptionBits state); 417 418 virtual IOReturn checkLink(uint32_t options = 0); 419 420 virtual IOReturn enableLTR(IOPCIDevice * device, bool enable); 421 422 virtual IOPCIEventSource * createEventSource(IOPCIDevice * device, 423 OSObject * owner, IOPCIEventSource::Action action, uint32_t options); 424 425 // Unused Padding 426 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 0); 427 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 1); 428 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 2); 429 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 3); 430 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 4); 431 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 5); 432 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 6); 433 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 7); 434 OSMetaClassDeclareReservedUnused(IOPCI2PCIBridge, 8); 435 436protected: 437 void allocateBridgeInterrupts(IOService * provider); 438 void startBridgeInterrupts(IOService * provider); 439 void enableBridgeInterrupts(void); 440 void disableBridgeInterrupts(void); 441 442private: 443 IOReturn setTunnelL1Enable(IOPCIDevice * device, IOService * client, 444 bool l1Enable); 445 446public: 447 void startBootDefer(IOService * provider); 448 449 bool filterInterrupt( IOFilterInterruptEventSource * source); 450 451 void handleInterrupt( IOInterruptEventSource * source, 452 int count ); 453 void timerProbe(IOTimerEventSource * es); 454}; 455 456#define kIOPCI2PCIBridgeName "IOPP" 457 458#endif /* ! _IOKIT_IOPCIBRIDGE_H */ 459