1 | /* $NetBSD: pcivar.h,v 1.113 2018/12/01 01:23:24 msaitoh Exp $ */ |
2 | |
3 | /* |
4 | * Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved. |
5 | * Copyright (c) 1994 Charles M. Hannum. All rights reserved. |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions |
9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. |
15 | * 3. All advertising materials mentioning features or use of this software |
16 | * must display the following acknowledgement: |
17 | * This product includes software developed by Charles M. Hannum. |
18 | * 4. The name of the author may not be used to endorse or promote products |
19 | * derived from this software without specific prior written permission. |
20 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
22 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
23 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
24 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
26 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
27 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
28 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
29 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
30 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | */ |
32 | |
33 | #ifndef _DEV_PCI_PCIVAR_H_ |
34 | #define _DEV_PCI_PCIVAR_H_ |
35 | |
36 | /* |
37 | * Definitions for PCI autoconfiguration. |
38 | * |
39 | * This file describes types and functions which are used for PCI |
40 | * configuration. Some of this information is machine-specific, and is |
41 | * provided by pci_machdep.h. |
42 | */ |
43 | |
44 | #include <sys/device.h> |
45 | #include <sys/pmf.h> |
46 | #include <sys/bus.h> |
47 | #include <dev/pci/pcireg.h> |
48 | #include <dev/pci/pci_verbose.h> |
49 | |
50 | /* |
51 | * Structures and definitions needed by the machine-dependent header. |
52 | */ |
53 | struct pcibus_attach_args; |
54 | struct pci_attach_args; |
55 | struct pci_softc; |
56 | |
57 | #ifdef _KERNEL |
58 | /* |
59 | * Machine-dependent definitions. |
60 | */ |
61 | #include <machine/pci_machdep.h> |
62 | |
63 | enum pci_override_idx { |
64 | PCI_OVERRIDE_CONF_READ = __BIT(0) |
65 | , PCI_OVERRIDE_CONF_WRITE = __BIT(1) |
66 | , PCI_OVERRIDE_INTR_MAP = __BIT(2) |
67 | , PCI_OVERRIDE_INTR_STRING = __BIT(3) |
68 | , PCI_OVERRIDE_INTR_EVCNT = __BIT(4) |
69 | , PCI_OVERRIDE_INTR_ESTABLISH = __BIT(5) |
70 | , PCI_OVERRIDE_INTR_DISESTABLISH = __BIT(6) |
71 | , PCI_OVERRIDE_MAKE_TAG = __BIT(7) |
72 | , PCI_OVERRIDE_DECOMPOSE_TAG = __BIT(8) |
73 | }; |
74 | |
75 | /* Only add new fields to the end of this structure! */ |
76 | struct pci_overrides { |
77 | pcireg_t (*ov_conf_read)(void *, pci_chipset_tag_t, pcitag_t, int); |
78 | void (*ov_conf_write)(void *, pci_chipset_tag_t, pcitag_t, int, |
79 | pcireg_t); |
80 | int (*ov_intr_map)(void *, const struct pci_attach_args *, |
81 | pci_intr_handle_t *); |
82 | const char *(*ov_intr_string)(void *, pci_chipset_tag_t, |
83 | pci_intr_handle_t, char *, size_t); |
84 | const struct evcnt *(*ov_intr_evcnt)(void *, pci_chipset_tag_t, |
85 | pci_intr_handle_t); |
86 | void *(*ov_intr_establish)(void *, pci_chipset_tag_t, pci_intr_handle_t, |
87 | int, int (*)(void *), void *); |
88 | void (*ov_intr_disestablish)(void *, pci_chipset_tag_t, void *); |
89 | pcitag_t (*ov_make_tag)(void *, pci_chipset_tag_t, int, int, int); |
90 | void (*ov_decompose_tag)(void *, pci_chipset_tag_t, pcitag_t, |
91 | int *, int *, int *); |
92 | }; |
93 | |
94 | /* |
95 | * PCI bus attach arguments. |
96 | */ |
97 | struct pcibus_attach_args { |
98 | char *_pba_busname; /* XXX placeholder */ |
99 | bus_space_tag_t pba_iot; /* pci i/o space tag */ |
100 | bus_space_tag_t pba_memt; /* pci mem space tag */ |
101 | bus_dma_tag_t pba_dmat; /* DMA tag */ |
102 | bus_dma_tag_t pba_dmat64; /* DMA tag */ |
103 | pci_chipset_tag_t pba_pc; |
104 | int pba_flags; /* flags; see below */ |
105 | |
106 | int pba_bus; /* PCI bus number */ |
107 | int pba_sub; /* pba_bus >= pba_sub: no |
108 | * buses are subordinate to |
109 | * pba_bus. |
110 | * |
111 | * pba_bus < pba_sub: buses |
112 | * [pba_bus + 1, pba_sub] are |
113 | * subordinate to pba_bus. |
114 | */ |
115 | |
116 | /* |
117 | * Pointer to the pcitag of our parent bridge. If there is no |
118 | * parent bridge, then we assume we are a root bus. |
119 | */ |
120 | pcitag_t *pba_bridgetag; |
121 | |
122 | /* |
123 | * Interrupt swizzling information. These fields |
124 | * are only used by secondary busses. |
125 | */ |
126 | u_int pba_intrswiz; /* how to swizzle pins */ |
127 | pcitag_t pba_intrtag; /* intr. appears to come from here */ |
128 | }; |
129 | |
130 | /* |
131 | * This is used by <machine/pci_machdep.h> to access the pba_pc member. It |
132 | * can't use it directly since pcibus_attach_args has yet to be defined. |
133 | */ |
134 | static __inline pci_chipset_tag_t |
135 | pcibus_attach_args_pc(struct pcibus_attach_args *pba) |
136 | { |
137 | return pba->pba_pc; |
138 | } |
139 | |
140 | /* |
141 | * PCI device attach arguments. |
142 | */ |
143 | struct pci_attach_args { |
144 | bus_space_tag_t pa_iot; /* pci i/o space tag */ |
145 | bus_space_tag_t pa_memt; /* pci mem space tag */ |
146 | bus_dma_tag_t pa_dmat; /* DMA tag */ |
147 | bus_dma_tag_t pa_dmat64; /* DMA tag */ |
148 | pci_chipset_tag_t pa_pc; |
149 | int pa_flags; /* flags; see below */ |
150 | |
151 | u_int pa_bus; |
152 | u_int pa_device; |
153 | u_int pa_function; |
154 | pcitag_t pa_tag; |
155 | pcireg_t pa_id, pa_class; |
156 | |
157 | /* |
158 | * Interrupt information. |
159 | * |
160 | * "Intrline" is used on systems whose firmware puts |
161 | * the right routing data into the line register in |
162 | * configuration space. The rest are used on systems |
163 | * that do not. |
164 | */ |
165 | u_int pa_intrswiz; /* how to swizzle pins if ppb */ |
166 | pcitag_t pa_intrtag; /* intr. appears to come from here */ |
167 | pci_intr_pin_t pa_intrpin; /* intr. appears on this pin */ |
168 | pci_intr_line_t pa_intrline; /* intr. routing information */ |
169 | pci_intr_pin_t pa_rawintrpin; /* unswizzled pin */ |
170 | }; |
171 | |
172 | /* |
173 | * This is used by <machine/pci_machdep.h> to access the pa_pc member. It |
174 | * can't use it directly since pci_attach_args has yet to be defined. |
175 | */ |
176 | static __inline pci_chipset_tag_t |
177 | pci_attach_args_pc(const struct pci_attach_args *pa) |
178 | { |
179 | return pa->pa_pc; |
180 | } |
181 | |
182 | /* |
183 | * Flags given in the bus and device attachment args. |
184 | */ |
185 | #define PCI_FLAGS_IO_OKAY 0x01 /* I/O space is okay */ |
186 | #define PCI_FLAGS_MEM_OKAY 0x02 /* memory space is okay */ |
187 | #define PCI_FLAGS_MRL_OKAY 0x04 /* Memory Read Line okay */ |
188 | #define PCI_FLAGS_MRM_OKAY 0x08 /* Memory Read Multiple okay */ |
189 | #define PCI_FLAGS_MWI_OKAY 0x10 /* Memory Write and Invalidate |
190 | okay */ |
191 | #define PCI_FLAGS_MSI_OKAY 0x20 /* Message Signaled Interrupts |
192 | okay */ |
193 | #define PCI_FLAGS_MSIX_OKAY 0x40 /* Message Signaled Interrupts |
194 | (Extended) okay */ |
195 | |
196 | /* |
197 | * PCI device 'quirks'. |
198 | * |
199 | * In general strange behaviour which can be handled by a driver (e.g. |
200 | * a bridge's inability to pass a type of access correctly) should be. |
201 | * The quirks table should only contain information which impacts |
202 | * the operation of the MI PCI code and which can't be pushed lower |
203 | * (e.g. because it's unacceptable to require a driver to be present |
204 | * for the information to be known). |
205 | */ |
206 | struct pci_quirkdata { |
207 | pci_vendor_id_t vendor; /* Vendor ID */ |
208 | pci_product_id_t product; /* Product ID */ |
209 | int quirks; /* quirks; see below */ |
210 | }; |
211 | #define PCI_QUIRK_MULTIFUNCTION __BIT(0) |
212 | #define PCI_QUIRK_MONOFUNCTION __BIT(1) |
213 | #define PCI_QUIRK_SKIP_FUNC(n) (4 << n) |
214 | #define PCI_QUIRK_SKIP_FUNC0 PCI_QUIRK_SKIP_FUNC(0) |
215 | #define PCI_QUIRK_SKIP_FUNC1 PCI_QUIRK_SKIP_FUNC(1) |
216 | #define PCI_QUIRK_SKIP_FUNC2 PCI_QUIRK_SKIP_FUNC(2) |
217 | #define PCI_QUIRK_SKIP_FUNC3 PCI_QUIRK_SKIP_FUNC(3) |
218 | #define PCI_QUIRK_SKIP_FUNC4 PCI_QUIRK_SKIP_FUNC(4) |
219 | #define PCI_QUIRK_SKIP_FUNC5 PCI_QUIRK_SKIP_FUNC(5) |
220 | #define PCI_QUIRK_SKIP_FUNC6 PCI_QUIRK_SKIP_FUNC(6) |
221 | #define PCI_QUIRK_SKIP_FUNC7 PCI_QUIRK_SKIP_FUNC(7) |
222 | #define PCI_QUIRK_HASEXTCNF __BIT(10) |
223 | #define PCI_QUIRK_NOEXTCNF __BIT(11) |
224 | |
225 | struct pci_conf_state { |
226 | pcireg_t reg[16]; |
227 | |
228 | /* For PCI-X */ |
229 | pcireg_t x_csr; /* Upper 16bits. Lower 16bits are read only */ |
230 | |
231 | /* For PCIe */ |
232 | uint16_t e_dcr; |
233 | uint16_t e_lcr; |
234 | uint16_t e_slcr; |
235 | uint16_t e_rcr; |
236 | uint16_t e_dcr2; |
237 | uint16_t e_lcr2; |
238 | |
239 | /* For MSI */ |
240 | pcireg_t msi_ctl; /* Upper 16bits. Lower 16bits are read only */ |
241 | pcireg_t msi_maddr; |
242 | pcireg_t msi_maddr64_hi; |
243 | pcireg_t msi_mdata; |
244 | pcireg_t msi_mask; |
245 | |
246 | /* For MSI-X */ |
247 | pcireg_t msix_ctl; /* Upper 16bits. Lower 16bits are read only */ |
248 | }; |
249 | |
250 | struct pci_range { |
251 | bus_addr_t r_offset; |
252 | bus_size_t r_size; |
253 | int r_flags; |
254 | }; |
255 | |
256 | struct pci_child { |
257 | device_t c_dev; |
258 | bool c_psok; |
259 | pcireg_t c_powerstate; |
260 | struct pci_conf_state c_conf; |
261 | struct pci_range c_range[8]; |
262 | }; |
263 | |
264 | struct pci_softc { |
265 | device_t sc_dev; |
266 | bus_space_tag_t sc_iot, sc_memt; |
267 | bus_dma_tag_t sc_dmat; |
268 | bus_dma_tag_t sc_dmat64; |
269 | pci_chipset_tag_t sc_pc; |
270 | int sc_bus, sc_maxndevs; |
271 | pcitag_t *sc_bridgetag; |
272 | u_int sc_intrswiz; |
273 | pcitag_t sc_intrtag; |
274 | int sc_flags; |
275 | /* accounting of child devices */ |
276 | struct pci_child sc_devices[32*8]; |
277 | #define PCI_SC_DEVICESC(d, f) sc_devices[(d) * 8 + (f)] |
278 | }; |
279 | |
280 | extern struct cfdriver pci_cd; |
281 | |
282 | extern bool pci_mapreg_map_enable_decode; |
283 | |
284 | int pcibusprint(void *, const char *); |
285 | |
286 | /* |
287 | * Configuration space access and utility functions. (Note that most, |
288 | * e.g. make_tag, conf_read, conf_write are declared by pci_machdep.h.) |
289 | */ |
290 | int pci_mapreg_probe(pci_chipset_tag_t, pcitag_t, int, pcireg_t *); |
291 | pcireg_t pci_mapreg_type(pci_chipset_tag_t, pcitag_t, int); |
292 | int pci_mapreg_info(pci_chipset_tag_t, pcitag_t, int, pcireg_t, |
293 | bus_addr_t *, bus_size_t *, int *); |
294 | int pci_mapreg_map(const struct pci_attach_args *, int, pcireg_t, int, |
295 | bus_space_tag_t *, bus_space_handle_t *, bus_addr_t *, |
296 | bus_size_t *); |
297 | int pci_mapreg_submap(const struct pci_attach_args *, int, pcireg_t, int, |
298 | bus_size_t, bus_size_t, bus_space_tag_t *, bus_space_handle_t *, |
299 | bus_addr_t *, bus_size_t *); |
300 | |
301 | |
302 | int pci_find_rom(const struct pci_attach_args *, bus_space_tag_t, |
303 | bus_space_handle_t, bus_size_t, |
304 | int, bus_space_handle_t *, bus_size_t *); |
305 | |
306 | int pci_get_capability(pci_chipset_tag_t, pcitag_t, int, int *, pcireg_t *); |
307 | int pci_get_ht_capability(pci_chipset_tag_t, pcitag_t, int, int *, |
308 | pcireg_t *); |
309 | int pci_get_ext_capability(pci_chipset_tag_t, pcitag_t, int, int *, |
310 | pcireg_t *); |
311 | |
312 | int pci_msi_count(pci_chipset_tag_t, pcitag_t); |
313 | int pci_msix_count(pci_chipset_tag_t, pcitag_t); |
314 | |
315 | /* |
316 | * Helper functions for autoconfiguration. |
317 | */ |
318 | #ifndef PCI_MACHDEP_ENUMERATE_BUS |
319 | int pci_enumerate_bus(struct pci_softc *, const int *, |
320 | int (*)(const struct pci_attach_args *), struct pci_attach_args *); |
321 | #endif |
322 | int pci_probe_device(struct pci_softc *, pcitag_t tag, |
323 | int (*)(const struct pci_attach_args *), |
324 | struct pci_attach_args *); |
325 | void pci_devinfo(pcireg_t, pcireg_t, int, char *, size_t); |
326 | void pci_aprint_devinfo_fancy(const struct pci_attach_args *, |
327 | const char *, const char *, int); |
328 | #define pci_aprint_devinfo(pap, naive) \ |
329 | pci_aprint_devinfo_fancy(pap, naive, NULL, 0); |
330 | void pci_conf_print(pci_chipset_tag_t, pcitag_t, |
331 | void (*)(pci_chipset_tag_t, pcitag_t, const pcireg_t *)); |
332 | const struct pci_quirkdata * |
333 | pci_lookup_quirkdata(pci_vendor_id_t, pci_product_id_t); |
334 | |
335 | /* |
336 | * Helper functions for user access to the PCI bus. |
337 | */ |
338 | struct proc; |
339 | int pci_devioctl(pci_chipset_tag_t, pcitag_t, u_long, void *, |
340 | int flag, struct lwp *); |
341 | |
342 | /* |
343 | * Power Management (PCI 2.2) |
344 | */ |
345 | |
346 | #define PCI_PWR_D0 0 |
347 | #define PCI_PWR_D1 1 |
348 | #define PCI_PWR_D2 2 |
349 | #define PCI_PWR_D3 3 |
350 | int pci_powerstate(pci_chipset_tag_t, pcitag_t, const int *, int *); |
351 | |
352 | /* |
353 | * Vital Product Data (PCI 2.2) |
354 | */ |
355 | int pci_vpd_read(pci_chipset_tag_t, pcitag_t, int, int, pcireg_t *); |
356 | int pci_vpd_write(pci_chipset_tag_t, pcitag_t, int, int, pcireg_t *); |
357 | |
358 | /* |
359 | * Misc. |
360 | */ |
361 | int pci_find_device(struct pci_attach_args *pa, |
362 | int (*match)(const struct pci_attach_args *)); |
363 | int pci_dma64_available(const struct pci_attach_args *); |
364 | void pci_conf_capture(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *); |
365 | void pci_conf_restore(pci_chipset_tag_t, pcitag_t, struct pci_conf_state *); |
366 | int pci_get_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t *); |
367 | int pci_set_powerstate(pci_chipset_tag_t, pcitag_t, pcireg_t); |
368 | int pci_activate(pci_chipset_tag_t, pcitag_t, device_t, |
369 | int (*)(pci_chipset_tag_t, pcitag_t, device_t, pcireg_t)); |
370 | int pci_activate_null(pci_chipset_tag_t, pcitag_t, device_t, pcireg_t); |
371 | int pci_chipset_tag_create(pci_chipset_tag_t, uint64_t, |
372 | const struct pci_overrides *, |
373 | void *, pci_chipset_tag_t *); |
374 | void pci_chipset_tag_destroy(pci_chipset_tag_t); |
375 | int pci_bus_devorder(pci_chipset_tag_t, int, uint8_t *, int); |
376 | void *pci_intr_establish_xname(pci_chipset_tag_t, pci_intr_handle_t, |
377 | int, int (*)(void *), void *, const char *); |
378 | #ifndef __HAVE_PCI_MSI_MSIX |
379 | typedef enum { |
380 | PCI_INTR_TYPE_INTX = 0, |
381 | PCI_INTR_TYPE_MSI, |
382 | PCI_INTR_TYPE_MSIX, |
383 | PCI_INTR_TYPE_SIZE, |
384 | } pci_intr_type_t; |
385 | |
386 | pci_intr_type_t |
387 | pci_intr_type(pci_chipset_tag_t, pci_intr_handle_t); |
388 | int pci_intr_alloc(const struct pci_attach_args *, pci_intr_handle_t **, |
389 | int *, pci_intr_type_t); |
390 | void pci_intr_release(pci_chipset_tag_t, pci_intr_handle_t *, int); |
391 | int pci_intx_alloc(const struct pci_attach_args *, pci_intr_handle_t **); |
392 | int pci_msi_alloc(const struct pci_attach_args *, pci_intr_handle_t **, |
393 | int *); |
394 | int pci_msi_alloc_exact(const struct pci_attach_args *, |
395 | pci_intr_handle_t **, int); |
396 | int pci_msix_alloc(const struct pci_attach_args *, pci_intr_handle_t **, |
397 | int *); |
398 | int pci_msix_alloc_exact(const struct pci_attach_args *, |
399 | pci_intr_handle_t **, int); |
400 | int pci_msix_alloc_map(const struct pci_attach_args *, pci_intr_handle_t **, |
401 | u_int *, int); |
402 | #endif |
403 | |
404 | /* |
405 | * Device abstraction for inheritance by elanpci(4), for example. |
406 | */ |
407 | int pcimatch(device_t, cfdata_t, void *); |
408 | void pciattach(device_t, device_t, void *); |
409 | int pcidetach(device_t, int); |
410 | void pcidevdetached(device_t, device_t); |
411 | int pcirescan(device_t, const char *, const int *); |
412 | |
413 | /* |
414 | * Interrupts. |
415 | */ |
416 | #define PCI_INTR_MPSAFE 1 |
417 | |
418 | int pci_intr_setattr(pci_chipset_tag_t, pci_intr_handle_t *, int, uint64_t); |
419 | |
420 | /* |
421 | * Local constants |
422 | */ |
423 | #define PCI_INTRSTR_LEN 64 |
424 | |
425 | #endif /* _KERNEL */ |
426 | |
427 | #endif /* _DEV_PCI_PCIVAR_H_ */ |
428 | |