1/* 2 * Copyright (c) 2002 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 24#ifndef _IOKIT_IOPCIPRIVATE_H 25#define _IOKIT_IOPCIPRIVATE_H 26 27#if defined(KERNEL) 28 29#include <IOKit/pci/IOPCIDevice.h> 30#include <IOKit/IORangeAllocator.h> 31#include <IOKit/IOInterruptController.h> 32#include <libkern/OSDebug.h> 33#include <IOKit/IOUserClient.h> 34 35#if !defined(__ppc__) 36#define USE_IOPCICONFIGURATOR 1 37#define USE_MSI 1 38#define USE_LEGACYINTS 1 39#endif 40 41#if defined(__i386__) || defined(__x86_64__) 42#define ACPI_SUPPORT 1 43#else 44#define ACPI_SUPPORT 0 45#endif 46 47struct IOPCIDeviceExpansionData 48{ 49 uint16_t powerCapability; 50 uint8_t pmSleepEnabled; // T if a client has enabled PCI Power Management 51 uint8_t pmControlStatus; // if >0 this device supports PCI Power Management 52 uint16_t sleepControlBits; // bits to set the control/status register to for sleep 53 uint16_t pmLastWakeBits; // bits read on wake 54 55 uint16_t expressCapability; 56 uint16_t expressCapabilities; 57 uint16_t expressASPMDefault; 58 uint8_t aspmCaps; 59 uint16_t l1pmCapability; 60 uint32_t l1pmCaps; 61 62 uint16_t aerCapability; 63 64 uint16_t msiCapability; 65 uint16_t msiControl; 66 uint16_t msiPhysVectorCount; 67 uint16_t msiVectorCount; 68 uint8_t msiMode; 69 uint8_t msiEnable; 70 uint64_t msiTable; 71 uint64_t msiPBA; 72 IOInterruptVector * msiVectors; 73 74 uint16_t latencyToleranceCapability; 75 76 uint8_t headerType; 77 uint8_t rootPort; 78 79 uint8_t configProt; 80 uint8_t pmActive; 81 uint8_t pmeUpdate; 82 uint8_t pmWait; 83 uint8_t pmState; 84 uint8_t pciPMState; 85 uint8_t pauseFlags; 86 uint8_t needsProbe; 87 uint8_t dead; 88 89 IOLock * lock; 90 struct IOPCIConfigEntry * configEntry; 91 92 IOPCIDevice * ltrDevice; 93 IOByteCount ltrOffset; 94 uint32_t ltrReg1; 95 uint8_t ltrReg2; 96 97 uint8_t tunnelL1Allow; 98 99#if ACPI_SUPPORT 100 int8_t psMethods[kIOPCIDevicePowerStateCount]; 101 int8_t lastPSMethod; 102#endif 103}; 104 105enum 106{ 107 kTunnelL1Disable = false, 108 kTunnelL1Enable = true, 109 kTunnelL1NotSet = 2 110}; 111 112#define expressV2(device) ((15 & device->reserved->expressCapabilities) > 1) 113 114enum 115{ 116 kIOPCIConfigShadowRegs = 32, 117 kIOPCIConfigEPShadowRegs = 16, 118 kIOPCIConfigBridgeShadowRegs = 32, 119 120 kIOPCIConfigShadowSize = kIOPCIConfigShadowRegs, 121 122 kIOPCISaveRegsMask = 0xFFFFFFFF 123// & ~(1 << (kIOPCIConfigVendorID >> 2)) 124}; 125 126struct IOPCIConfigShadow 127{ 128 uint32_t savedConfig[kIOPCIConfigShadowSize]; 129 130 // express save 131 uint16_t savedDeviceControl; 132 uint16_t savedLinkControl; 133 uint16_t savedSlotControl; 134 uint16_t savedDeviceControl2; 135 uint16_t savedLinkControl2; 136 uint16_t savedSlotControl2; 137 138 // msi save 139 uint32_t savedMSIAddress0; 140 uint32_t savedMSIAddress1; 141 uint32_t savedMSIData; 142 uint16_t savedMSIControl; 143 uint32_t savedMSIEnable; 144 145 // l1pm save 146 uint32_t savedL1PM0; 147 uint32_t savedL1PM1; 148 149 // ltr save 150 uint32_t savedLTR; 151 152 // aer save 153 uint32_t savedAERCapsControl; // 0x18 154 uint32_t savedAERSeverity; // 0x0C 155 uint32_t savedAERUMask; // 0x08 156 uint32_t savedAERCMask; // 0x14 157 uint32_t savedAERRootCommand; // 0x2c 158 159 // 160 uint32_t flags; 161 queue_chain_t link; 162 queue_head_t dependents; 163 IOPCIDevice * tunnelRoot; 164 IOPCIDevice * device; 165 IOPCI2PCIBridge * bridge; 166 OSObject * tunnelID; 167 IOPCIDeviceConfigHandler handler; 168 void * handlerRef; 169 uint64_t restoreCount; 170}; 171 172#define configShadow(device) ((IOPCIConfigShadow *) &device->savedConfig[0]) 173 174 175// flags in kIOPCIConfigShadowFlags 176enum 177{ 178 kIOPCIConfigShadowValid = 0x00000001, 179 kIOPCIConfigShadowBridge = 0x00000002, 180 kIOPCIConfigShadowHostBridge = 0x00000004, 181 kIOPCIConfigShadowBridgeDriver = 0x00000008, 182 kIOPCIConfigShadowBridgeInterrupts = 0x00000010, 183 kIOPCIConfigShadowSleepLinkDisable = 0x00000020, 184 kIOPCIConfigShadowSleepReset = 0x00000040, 185 kIOPCIConfigShadowHotplug = 0x00000080, 186 kIOPCIConfigShadowVolatile = 0x00000100, 187 kIOPCIConfigShadowWakeL1PMDisable = 0x00000200, 188}; 189 190// whatToDo for setDevicePowerState() 191enum 192{ 193 kSaveDeviceState = 0, 194 kRestoreDeviceState = 1, 195 kSaveBridgeState = 2, 196 kRestoreBridgeState = 3 197}; 198 199enum 200{ 201 kMachineRestoreBridges = 0x00000001, 202 kMachineRestoreEarlyDevices = 0x00000002, 203 kMachineRestoreDehibernate = 0x00000004, 204 kMachineRestoreTunnels = 0x00000008, 205}; 206 207enum 208{ 209 kIOPCIRestoreDeviceStateEarly = 0x00000001 210}; 211 212#define PCI_ADDRESS_TUPLE(device) \ 213 device->space.s.busNum, \ 214 device->space.s.deviceNum, \ 215 device->space.s.functionNum 216 217 218/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 219 220#define kIOPCIEjectableKey "IOPCIEjectable" 221#define kIOPCIHotPlugKey "IOPCIHotPlug" 222#define kIOPCILinkChangeKey "IOPCILinkChange" 223#define kIOPCITunnelLinkChangeKey "IOPCITunnelLinkChange" 224#define kIOPCITunnelBootDeferKey "IOPCITunnelBootDefer" 225#define kIOPCIResetKey "IOPCIReset" 226#define kIOPCIOnlineKey "IOPCIOnline" 227#define kIOPCIConfiguredKey "IOPCIConfigured" 228#define kIOPCIResourcedKey "IOPCIResourced" 229#define kIOPCIPMCSStateKey "IOPCIPMCSState" 230 231#ifndef kACPIDevicePathKey 232#define kACPIDevicePathKey "acpi-path" 233#endif 234 235#ifndef kACPIDevicePropertiesKey 236#define kACPIDevicePropertiesKey "device-properties" 237#endif 238 239#ifndef kACPIPCILinkChangeKey 240#define kACPIPCILinkChangeKey "pci-supports-link-change" 241#endif 242 243#define kIOPCIExpressASPMDefaultKey "pci-aspm-default" 244 245#define kIOPCIExpressMaxLatencyKey "pci-max-latency" 246 247#define kIOPCIExpressErrorUncorrectableMaskKey "pci-aer-uncorrectable" 248#define kIOPCIExpressErrorUncorrectableSeverityKey "pci-aer-uncorrectable-severity" 249#define kIOPCIExpressErrorCorrectableMaskKey "pci-aer-correctable" 250#define kIOPCIExpressErrorControlKey "pci-aer-control" 251 252// property to disable LTR on wake 253#define kIOPMPCIWakeL1PMDisableKey "pci-wake-l1pm-disable" 254 255enum 256{ 257 kIOPCIExpressASPML0s = 0x00000001, 258 kIOPCIExpressASPML1 = 0x00000002 259}; 260 261#define kIOPCIExpressL1PMControlKey "pci-l1pm-control" 262 263#ifndef kIODebugArgumentsKey 264#define kIODebugArgumentsKey "IODebugArguments" 265#endif 266 267#ifndef kIOMemoryDescriptorOptionsKey 268#define kIOMemoryDescriptorOptionsKey "IOMemoryDescriptorOptions" 269#endif 270 271extern const IORegistryPlane * gIOPCIACPIPlane; 272extern const OSSymbol * gIOPlatformDeviceASPMEnableKey; 273extern uint32_t gIOPCIFlags; 274extern const OSSymbol * gIOPlatformGetMessagedInterruptControllerKey; 275extern const OSSymbol * gIOPlatformGetMessagedInterruptAddressKey; 276extern const OSSymbol * gIOPCIThunderboltKey; 277extern const OSSymbol * gIOPolledInterfaceActiveKey; 278#if ACPI_SUPPORT 279extern const OSSymbol * gIOPCIPSMethods[kIOPCIDevicePowerStateCount]; 280#endif 281 282extern IOReturn IOPCIRegisterPowerDriver(IOService * service, bool hostbridge); 283 284#define arrayCount(x) (sizeof(x) / sizeof(x[0])) 285 286enum 287{ 288 kMSIX = 0x01 289}; 290 291/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 292 293class IOPCIMessagedInterruptController : public IOInterruptController 294{ 295 OSDeclareDefaultStructors( IOPCIMessagedInterruptController ) 296 297protected: 298 299 // The base global system interrupt number. 300 301 SInt32 _vectorBase; 302 UInt32 _vectorCount; 303 UInt32 _parentOffset; 304 305 IORangeAllocator * _messagedInterruptsAllocator; 306 307public: 308 309 virtual IOReturn registerInterrupt(IOService *nub, int source, 310 void *target, 311 IOInterruptHandler handler, 312 void *refCon); 313 virtual IOReturn unregisterInterrupt(IOService *nub, int source); 314 315 virtual IOReturn getInterruptType(IOService *nub, int source, 316 int *interruptType); 317 318 virtual IOReturn enableInterrupt(IOService *nub, int source); 319 virtual IOReturn disableInterrupt(IOService *nub, int source); 320 321 virtual IOReturn handleInterrupt(void *refCon, IOService *nub, 322 int source); 323 324public: 325 326 static IOInterruptVector * allocVectors(uint32_t count); 327 static void initDevice(IOPCIDevice * device, IOPCIConfigShadow * shadow); 328 static void saveDeviceState(IOPCIDevice * device, IOPCIConfigShadow * shadow); 329 static void restoreDeviceState(IOPCIDevice * device, IOPCIConfigShadow * shadow); 330 331 void enableDeviceMSI(IOPCIDevice *device); 332 void disableDeviceMSI(IOPCIDevice *device); 333 334 bool init(UInt32 numVectors, UInt32 baseVector); 335 336 bool init(UInt32 numVectors); 337 338 bool reserveVectors(UInt32 vector, UInt32 count); 339 340 virtual void initVector( IOInterruptVectorNumber vectorNumber, 341 IOInterruptVector * vector ); 342 343 virtual int getVectorType(IOInterruptVectorNumber vectorNumber, IOInterruptVector *vector); 344 345 virtual bool vectorCanBeShared( IOInterruptVectorNumber vectorNumber, 346 IOInterruptVector * vector ); 347 348 virtual void enableVector( IOInterruptVectorNumber vectorNumber, 349 IOInterruptVector * vector ); 350 351 virtual void disableVectorHard( IOInterruptVectorNumber vectorNumber, 352 IOInterruptVector * vector ); 353 354 virtual bool addDeviceInterruptProperties( 355 IORegistryEntry * device, 356 UInt32 controllerIndex, 357 UInt32 interruptFlags, 358 SInt32 * deviceIndex); 359 360 IOReturn allocateDeviceInterrupts( 361 IOService * entry, uint32_t numVectors, uint32_t msiConfig, 362 uint64_t * msiAddress = 0, uint32_t * msiData = 0); 363 IOReturn deallocateDeviceInterrupts(IOService * device); 364 365 virtual void deallocateInterrupt(UInt32 vector); 366 367protected: 368 virtual bool allocateInterruptVectors( IOService *device, 369 uint32_t numVectors, 370 IORangeScalar *rangeStartOut); 371 372}; 373 374/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 375 376class IOPCIDiagnosticsClient : public IOUserClient 377{ 378 OSDeclareDefaultStructors(IOPCIDiagnosticsClient) 379 380 friend class IOPCIBridge; 381 382 IOPCIBridge * owner; 383 384public: 385 virtual IOReturn clientClose(void); 386 virtual IOService * getService(void); 387 virtual IOReturn setProperties(OSObject * properties); 388 virtual IOReturn externalMethod(uint32_t selector, IOExternalMethodArguments * args, 389 IOExternalMethodDispatch * dispatch, OSObject * target, void * reference); 390}; 391 392#endif /* defined(KERNEL) */ 393 394enum 395{ 396 kIOPCIDiagnosticsClientType = 0x99000001 397}; 398 399enum 400{ 401 kIOPCIProbeOptionLinkInt = 0x40000000, 402}; 403 404 405enum { 406 kIOPCIDiagnosticsMethodRead = 0, 407 kIOPCIDiagnosticsMethodWrite = 1, 408 kIOPCIDiagnosticsMethodCount 409}; 410 411struct IOPCIDiagnosticsParameters 412{ 413 uint32_t options; 414 uint32_t spaceType; 415 uint32_t bitWidth; 416 uint32_t _resv; 417 uint64_t value; 418 union 419 { 420 uint64_t addr64; 421 struct { 422 unsigned int offset :16; 423 unsigned int function :3; 424 unsigned int device :5; 425 unsigned int bus :8; 426 unsigned int segment :16; 427 unsigned int reserved :16; 428 } pci; 429 } address; 430}; 431typedef struct IOPCIDiagnosticsParameters IOPCIDiagnosticsParameters; 432 433#endif /* ! _IOKIT_IOPCIPRIVATE_H */ 434 435