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