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