xref: /haiku/src/add-ons/kernel/bus_managers/pci/pci.h (revision 52f7c9389475e19fc21487b38064b4390eeb6fea)
1 /*
2  * Copyright 2003-2008, Marcus Overhagen. All rights reserved.
3  * Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 #ifndef __PCI_H__
8 #define __PCI_H__
9 
10 #include <PCI.h>
11 
12 #ifdef __cplusplus
13   #include <VectorMap.h>
14 #endif
15 
16 #include "pci_controller.h"
17 
18 #if defined(__i386__) || defined(__x86_64__)
19 #include "pci_arch_info.h"
20 #endif
21 
22 #define TRACE_PCI
23 #ifndef TRACE_PCI
24 #	define TRACE(x)
25 #else
26 #	define TRACE(x) dprintf x
27 #endif
28 
29 #ifdef __cplusplus
30 
31 struct PCIDev;
32 
33 struct PCIBus {
34 	PCIBus *			next;
35 	PCIDev *			parent;
36 	PCIDev *			child;
37 	uint8				domain;
38 	uint8				bus;
39 };
40 
41 struct PCIDev {
42 	PCIDev *			next;
43 	PCIBus *			parent;
44 	PCIBus *			child;
45 	uint8				domain;
46 	uint8				bus;
47 	uint8				device;
48 	uint8				function;
49 	pci_info			info;
50 #if defined(__i386__) || defined(__x86_64__)
51 	pci_arch_info		arch_info;
52 #endif
53 };
54 
55 
56 struct domain_data {
57 	// These two are set in PCI::AddController:
58 	pci_controller *	controller;
59 	void *				controller_cookie;
60 
61 	// All the rest is set in PCI::InitDomainData
62 	int					max_bus_devices;
63 };
64 
65 
66 class PCI {
67 public:
68 							PCI();
69 							~PCI();
70 
71 			void			InitDomainData();
72 			void			InitBus();
73 
74 			status_t		AddController(pci_controller *controller,
75 								void *controller_cookie);
76 
77 			status_t		GetNthInfo(long index, pci_info *outInfo);
78 
79 			status_t		ReadConfig(uint8 domain, uint8 bus, uint8 device,
80 								uint8 function, uint16 offset, uint8 size,
81 								uint32 *value);
82 			uint32			ReadConfig(uint8 domain, uint8 bus, uint8 device,
83 								uint8 function, uint16 offset, uint8 size);
84 			uint32			ReadConfig(PCIDev *device, uint16 offset,
85 								uint8 size);
86 
87 			status_t		WriteConfig(uint8 domain, uint8 bus, uint8 device,
88 								uint8 function, uint16 offset, uint8 size,
89 								uint32 value);
90 			status_t		WriteConfig(PCIDev *device, uint16 offset,
91 								uint8 size, uint32 value);
92 
93 			status_t		FindCapability(uint8 domain, uint8 bus,
94 								uint8 device, uint8 function, uint8 capID,
95 								uint8 *offset = NULL);
96 			status_t		FindCapability(PCIDev *device, uint8 capID,
97 								uint8 *offset = NULL);
98 			status_t		FindExtendedCapability(uint8 domain, uint8 bus,
99 								uint8 device, uint8 function, uint16 capID,
100 								uint16 *offset = NULL);
101 			status_t		FindExtendedCapability(PCIDev *device,
102 								uint16 capID, uint16 *offset = NULL);
103 			status_t		FindHTCapability(uint8 domain, uint8 bus,
104 								uint8 device, uint8 function, uint16 capID,
105 								uint8 *offset);
106 			status_t		FindHTCapability(PCIDev *device,
107 								uint16 capID, uint8 *offset = NULL);
108 
109 			status_t		ResolveVirtualBus(uint8 virtualBus, uint8 *domain,
110 								uint8 *bus);
111 
112 			PCIDev *		FindDevice(uint8 domain, uint8 bus, uint8 device,
113 								uint8 function);
114 
115 			void			ClearDeviceStatus(PCIBus *bus, bool dumpStatus);
116 
117 			uint8			GetPowerstate(PCIDev *device);
118 			status_t		GetPowerstate(uint8 domain, uint8 bus, uint8 device,
119 								uint8 function, uint8* state);
120 			void			SetPowerstate(PCIDev *device, uint8 state);
121 			status_t		SetPowerstate(uint8 domain, uint8 bus, uint8 device,
122 								uint8 function, uint8 newState);
123 
124 			void			RefreshDeviceInfo();
125 
126 			status_t		UpdateInterruptLine(uint8 domain, uint8 bus,
127 								uint8 device, uint8 function,
128 								uint8 newInterruptLineValue);
129 
130 private:
131 			void			_EnumerateBus(uint8 domain, uint8 bus,
132 								uint8 *subordinateBus = NULL);
133 
134 			void			_FixupDevices(uint8 domain, uint8 bus);
135 
136 			void			_DiscoverBus(PCIBus *bus);
137 			void			_DiscoverDevice(PCIBus *bus, uint8 dev,
138 								uint8 function);
139 
140 			PCIDev *		_CreateDevice(PCIBus *parent, uint8 dev,
141 								uint8 function);
142 			PCIBus *		_CreateBus(PCIDev *parent, uint8 domain,
143 								uint8 bus);
144 
145 			status_t		_GetNthInfo(PCIBus *bus, long *currentIndex,
146 								long wantIndex, pci_info *outInfo);
147 			void			_ReadBasicInfo(PCIDev *dev);
148 			void			_ReadHeaderInfo(PCIDev *dev);
149 
150 			void			_ConfigureBridges(PCIBus *bus);
151 			void			_RefreshDeviceInfo(PCIBus *bus);
152 
153 			uint64			_BarSize(uint64 bits);
154 			size_t			_GetBarInfo(PCIDev *dev, uint8 offset,
155 								uint32 &ramAddress, uint32 &pciAddress,
156 								uint32 &size, uint8 &flags,
157 								uint32 *highRAMAddress = NULL,
158 								uint32 *highPCIAddress = NULL,
159 								uint32 *highSize = NULL);
160 			void			_GetRomBarInfo(PCIDev *dev, uint8 offset,
161 								uint32 &address, uint32 *size = NULL,
162 								uint8 *flags = NULL);
163 
164 			domain_data *	_GetDomainData(uint8 domain);
165 
166 			status_t		_CreateVirtualBus(uint8 domain, uint8 bus,
167 								uint8 *virtualBus);
168 
169 			int				_NumFunctions(uint8 domain, uint8 bus,
170 								uint8 device);
171 			PCIDev *		_FindDevice(PCIBus *current, uint8 domain,
172 								uint8 bus, uint8 device, uint8 function);
173 
174 private:
175 	PCIBus *				fRootBus;
176 
177 	enum { MAX_PCI_DOMAINS = 8 };
178 
179 	domain_data				fDomainData[MAX_PCI_DOMAINS];
180 	uint8					fDomainCount;
181 	bool					fBusEnumeration;
182 
183 	typedef VectorMap<uint8, uint16> VirtualBusMap;
184 
185 	VirtualBusMap			fVirtualBusMap;
186 	int						fNextVirtualBus;
187 };
188 
189 extern PCI *gPCI;
190 
191 #endif // __cplusplus
192 
193 
194 #ifdef __cplusplus
195 extern "C" {
196 #endif
197 
198 status_t	pci_init(void);
199 void		pci_uninit(void);
200 
201 long		pci_get_nth_pci_info(long index, pci_info *outInfo);
202 
203 uint32		pci_read_config(uint8 virtualBus, uint8 device, uint8 function,
204 				uint16 offset, uint8 size);
205 void		pci_write_config(uint8 virtualBus, uint8 device, uint8 function,
206 				uint16 offset, uint8 size, uint32 value);
207 
208 void		__pci_resolve_virtual_bus(uint8 virtualBus, uint8 *domain, uint8 *bus);
209 
210 #ifdef __cplusplus
211 }
212 #endif
213 
214 #endif	/* __PCI_H__ */
215