Line data Source code
1 : /* $OpenBSD: pci_machdep.c,v 1.69 2018/08/19 08:23:47 kettenis Exp $ */
2 : /* $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
6 : * All rights reserved.
7 : *
8 : * This code is derived from software contributed to The NetBSD Foundation
9 : * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
10 : * NASA Ames Research Center.
11 : *
12 : * Redistribution and use in source and binary forms, with or without
13 : * modification, are permitted provided that the following conditions
14 : * are met:
15 : * 1. Redistributions of source code must retain the above copyright
16 : * notice, this list of conditions and the following disclaimer.
17 : * 2. Redistributions in binary form must reproduce the above copyright
18 : * notice, this list of conditions and the following disclaimer in the
19 : * documentation and/or other materials provided with the distribution.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 : * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 : * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 : * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 : * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 : * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 : * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 : * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 : * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 : * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 : * POSSIBILITY OF SUCH DAMAGE.
32 : */
33 :
34 : /*
35 : * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
36 : * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
37 : *
38 : * Redistribution and use in source and binary forms, with or without
39 : * modification, are permitted provided that the following conditions
40 : * are met:
41 : * 1. Redistributions of source code must retain the above copyright
42 : * notice, this list of conditions and the following disclaimer.
43 : * 2. Redistributions in binary form must reproduce the above copyright
44 : * notice, this list of conditions and the following disclaimer in the
45 : * documentation and/or other materials provided with the distribution.
46 : * 3. All advertising materials mentioning features or use of this software
47 : * must display the following acknowledgement:
48 : * This product includes software developed by Charles M. Hannum.
49 : * 4. The name of the author may not be used to endorse or promote products
50 : * derived from this software without specific prior written permission.
51 : *
52 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
53 : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
54 : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
55 : * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
56 : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
57 : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
58 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
59 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
61 : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62 : */
63 :
64 : /*
65 : * Machine-specific functions for PCI autoconfiguration.
66 : */
67 :
68 : #include <sys/param.h>
69 : #include <sys/systm.h>
70 : #include <sys/extent.h>
71 : #include <sys/malloc.h>
72 :
73 : #include <machine/bus.h>
74 :
75 : #include <machine/pio.h>
76 : #include <machine/intr.h>
77 : #include <machine/biosvar.h>
78 :
79 : #include <dev/isa/isareg.h>
80 : #include <dev/pci/pcivar.h>
81 : #include <dev/pci/pcireg.h>
82 : #include <dev/pci/pcidevs.h>
83 : #include <dev/pci/ppbreg.h>
84 :
85 : #include "ioapic.h"
86 :
87 : #if NIOAPIC > 0
88 : #include <machine/i82093var.h>
89 : #include <machine/mpbiosvar.h>
90 : #endif
91 :
92 : /*
93 : * Memory Mapped Configuration space access.
94 : *
95 : * Since mapping the whole configuration space will cost us up to
96 : * 256MB of kernel virtual memory, we use seperate mappings per bus.
97 : * The mappings are created on-demand, such that we only use kernel
98 : * virtual memory for busses that are actually present.
99 : */
100 : bus_addr_t pci_mcfg_addr;
101 : int pci_mcfg_min_bus, pci_mcfg_max_bus;
102 : bus_space_tag_t pci_mcfgt;
103 : bus_space_handle_t pci_mcfgh[256];
104 :
105 : struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
106 :
107 : #define PCI_CONF_LOCK() \
108 : do { \
109 : mtx_enter(&pci_conf_lock); \
110 : } while (0)
111 :
112 : #define PCI_CONF_UNLOCK() \
113 : do { \
114 : mtx_leave(&pci_conf_lock); \
115 : } while (0)
116 :
117 : #define PCI_MODE1_ENABLE 0x80000000UL
118 : #define PCI_MODE1_ADDRESS_REG 0x0cf8
119 : #define PCI_MODE1_DATA_REG 0x0cfc
120 :
121 : /*
122 : * PCI doesn't have any special needs; just use the generic versions
123 : * of these functions.
124 : */
125 : struct bus_dma_tag pci_bus_dma_tag = {
126 : NULL, /* _may_bounce */
127 : _bus_dmamap_create,
128 : _bus_dmamap_destroy,
129 : _bus_dmamap_load,
130 : _bus_dmamap_load_mbuf,
131 : _bus_dmamap_load_uio,
132 : _bus_dmamap_load_raw,
133 : _bus_dmamap_unload,
134 : _bus_dmamap_sync,
135 : _bus_dmamem_alloc,
136 : _bus_dmamem_alloc_range,
137 : _bus_dmamem_free,
138 : _bus_dmamem_map,
139 : _bus_dmamem_unmap,
140 : _bus_dmamem_mmap,
141 : };
142 :
143 : void
144 0 : pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
145 : int min_bus, int max_bus)
146 : {
147 0 : if (segment == 0) {
148 0 : pci_mcfgt = iot;
149 0 : pci_mcfg_addr = addr;
150 0 : pci_mcfg_min_bus = min_bus;
151 0 : pci_mcfg_max_bus = max_bus;
152 0 : }
153 0 : }
154 :
155 : pci_chipset_tag_t
156 0 : pci_lookup_segment(int segment)
157 : {
158 0 : KASSERT(segment == 0);
159 0 : return NULL;
160 : }
161 :
162 : void
163 0 : pci_attach_hook(struct device *parent, struct device *self,
164 : struct pcibus_attach_args *pba)
165 : {
166 0 : pci_chipset_tag_t pc = pba->pba_pc;
167 : pcitag_t tag;
168 : pcireg_t id, class;
169 :
170 0 : if (pba->pba_bus != 0)
171 0 : return;
172 :
173 : /*
174 : * In order to decide whether the system supports MSI we look
175 : * at the host bridge, which should be device 0 function 0 on
176 : * bus 0. It is better to not enable MSI on systems that
177 : * support it than the other way around, so be conservative
178 : * here. So we don't enable MSI if we don't find a host
179 : * bridge there. We also deliberately don't enable MSI on
180 : * chipsets from low-end manifacturers like VIA and SiS.
181 : */
182 0 : tag = pci_make_tag(pc, 0, 0, 0);
183 0 : id = pci_conf_read(pc, tag, PCI_ID_REG);
184 0 : class = pci_conf_read(pc, tag, PCI_CLASS_REG);
185 :
186 0 : if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
187 0 : PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST)
188 0 : return;
189 :
190 0 : switch (PCI_VENDOR(id)) {
191 : case PCI_VENDOR_INTEL:
192 : /*
193 : * In the wonderful world of virtualization you can
194 : * have the latest 64-bit AMD multicore CPU behind a
195 : * prehistoric Intel host bridge. Give them what they
196 : * deserve.
197 : */
198 0 : switch (PCI_PRODUCT(id)) {
199 : case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
200 : case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
201 : break;
202 : default:
203 0 : pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
204 0 : break;
205 : }
206 : break;
207 : case PCI_VENDOR_NVIDIA:
208 : case PCI_VENDOR_AMD:
209 0 : pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
210 0 : break;
211 : }
212 :
213 : /*
214 : * Don't enable MSI on a HyperTransport bus. In order to
215 : * determine that bus 0 is a HyperTransport bus, we look at
216 : * device 24 function 0, which is the HyperTransport
217 : * host/primary interface integrated on most 64-bit AMD CPUs.
218 : * If that device has a HyperTransport capability, bus 0 must
219 : * be a HyperTransport bus and we disable MSI.
220 : */
221 0 : tag = pci_make_tag(pc, 0, 24, 0);
222 0 : if (pci_get_capability(pc, tag, PCI_CAP_HT, NULL, NULL))
223 0 : pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
224 0 : }
225 :
226 : int
227 0 : pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
228 : {
229 0 : return (32);
230 : }
231 :
232 : pcitag_t
233 0 : pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
234 : {
235 0 : if (bus >= 256 || device >= 32 || function >= 8)
236 0 : panic("pci_make_tag: bad request");
237 :
238 0 : return (PCI_MODE1_ENABLE |
239 0 : (bus << 16) | (device << 11) | (function << 8));
240 : }
241 :
242 : void
243 0 : pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
244 : {
245 0 : if (bp != NULL)
246 0 : *bp = (tag >> 16) & 0xff;
247 0 : if (dp != NULL)
248 0 : *dp = (tag >> 11) & 0x1f;
249 0 : if (fp != NULL)
250 0 : *fp = (tag >> 8) & 0x7;
251 0 : }
252 :
253 : int
254 0 : pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
255 : {
256 0 : int bus;
257 :
258 0 : if (pci_mcfg_addr) {
259 0 : pci_decompose_tag(pc, tag, &bus, NULL, NULL);
260 0 : if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
261 0 : return PCIE_CONFIG_SPACE_SIZE;
262 : }
263 :
264 0 : return PCI_CONFIG_SPACE_SIZE;
265 0 : }
266 :
267 : void
268 0 : pci_mcfg_map_bus(int bus)
269 : {
270 0 : if (pci_mcfgh[bus])
271 : return;
272 :
273 0 : if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
274 : 0, &pci_mcfgh[bus]))
275 0 : panic("pci_conf_read: cannot map mcfg space");
276 0 : }
277 :
278 : pcireg_t
279 0 : pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
280 : {
281 : pcireg_t data;
282 0 : int bus;
283 :
284 0 : KASSERT((reg & 0x3) == 0);
285 :
286 0 : if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
287 0 : pci_decompose_tag(pc, tag, &bus, NULL, NULL);
288 0 : if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
289 0 : pci_mcfg_map_bus(bus);
290 0 : data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
291 : (tag & 0x000ff00) << 4 | reg);
292 0 : return data;
293 : }
294 : }
295 :
296 0 : PCI_CONF_LOCK();
297 0 : outl(PCI_MODE1_ADDRESS_REG, tag | reg);
298 0 : data = inl(PCI_MODE1_DATA_REG);
299 0 : outl(PCI_MODE1_ADDRESS_REG, 0);
300 0 : PCI_CONF_UNLOCK();
301 :
302 0 : return data;
303 0 : }
304 :
305 : void
306 0 : pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
307 : {
308 0 : int bus;
309 :
310 0 : KASSERT((reg & 0x3) == 0);
311 :
312 0 : if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
313 0 : pci_decompose_tag(pc, tag, &bus, NULL, NULL);
314 0 : if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
315 0 : pci_mcfg_map_bus(bus);
316 0 : bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
317 : (tag & 0x000ff00) << 4 | reg, data);
318 0 : return;
319 : }
320 : }
321 :
322 0 : PCI_CONF_LOCK();
323 0 : outl(PCI_MODE1_ADDRESS_REG, tag | reg);
324 0 : outl(PCI_MODE1_DATA_REG, data);
325 0 : outl(PCI_MODE1_ADDRESS_REG, 0);
326 0 : PCI_CONF_UNLOCK();
327 0 : }
328 :
329 : void msi_hwmask(struct pic *, int);
330 : void msi_hwunmask(struct pic *, int);
331 : void msi_addroute(struct pic *, struct cpu_info *, int, int, int);
332 : void msi_delroute(struct pic *, struct cpu_info *, int, int, int);
333 :
334 : struct pic msi_pic = {
335 : {0, {NULL}, NULL, 0, "msi", NULL, 0, 0},
336 : PIC_MSI,
337 : #ifdef MULTIPROCESSOR
338 : {},
339 : #endif
340 : msi_hwmask,
341 : msi_hwunmask,
342 : msi_addroute,
343 : msi_delroute,
344 : NULL,
345 : ioapic_edge_stubs
346 : };
347 :
348 : void
349 0 : msi_hwmask(struct pic *pic, int pin)
350 : {
351 0 : }
352 :
353 : void
354 0 : msi_hwunmask(struct pic *pic, int pin)
355 : {
356 0 : }
357 :
358 : void
359 0 : msi_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
360 : {
361 : pci_chipset_tag_t pc = NULL; /* XXX */
362 : pcitag_t tag = pin;
363 0 : pcireg_t reg, addr;
364 0 : int off;
365 :
366 0 : if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, ®) == 0)
367 0 : panic("%s: no msi capability", __func__);
368 :
369 0 : addr = 0xfee00000UL | (ci->ci_apicid << 12);
370 :
371 0 : if (reg & PCI_MSI_MC_C64) {
372 : pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
373 0 : pci_conf_write(pc, tag, off + PCI_MSI_MAU32, 0);
374 0 : pci_conf_write(pc, tag, off + PCI_MSI_MD64, vec);
375 0 : } else {
376 : pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
377 0 : pci_conf_write(pc, tag, off + PCI_MSI_MD32, vec);
378 : }
379 0 : pci_conf_write(pc, tag, off, reg | PCI_MSI_MC_MSIE);
380 0 : }
381 :
382 : void
383 0 : msi_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
384 : {
385 : pci_chipset_tag_t pc = NULL; /* XXX */
386 : pcitag_t tag = pin;
387 0 : pcireg_t reg;
388 0 : int off;
389 :
390 0 : if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, ®))
391 0 : pci_conf_write(pc, tag, off, reg & ~PCI_MSI_MC_MSIE);
392 0 : }
393 :
394 : int
395 0 : pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
396 : {
397 0 : pci_chipset_tag_t pc = pa->pa_pc;
398 0 : pcitag_t tag = pa->pa_tag;
399 :
400 0 : if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
401 0 : pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
402 0 : return 1;
403 :
404 0 : ihp->tag = tag;
405 0 : ihp->line = APIC_INT_VIA_MSG;
406 0 : ihp->pin = 0;
407 0 : return 0;
408 0 : }
409 :
410 : void msix_hwmask(struct pic *, int);
411 : void msix_hwunmask(struct pic *, int);
412 : void msix_addroute(struct pic *, struct cpu_info *, int, int, int);
413 : void msix_delroute(struct pic *, struct cpu_info *, int, int, int);
414 :
415 : struct pic msix_pic = {
416 : {0, {NULL}, NULL, 0, "msix", NULL, 0, 0},
417 : PIC_MSI,
418 : #ifdef MULTIPROCESSOR
419 : {},
420 : #endif
421 : msix_hwmask,
422 : msix_hwunmask,
423 : msix_addroute,
424 : msix_delroute,
425 : NULL,
426 : ioapic_edge_stubs
427 : };
428 :
429 : /*
430 : * We pack the MSI-X vector number into the lower 8 bits of the PCI
431 : * tag and use that as the MSI-X "PIC" pin number. This allows us to
432 : * address 256 MSI-X vectors which ought to be enough for anybody.
433 : */
434 : #define PCI_MSIX_VEC_MASK 0xff
435 : #define PCI_MSIX_VEC(pin) ((pin) & PCI_MSIX_VEC_MASK)
436 : #define PCI_MSIX_TAG(pin) ((pin) & ~PCI_MSIX_VEC_MASK)
437 : #define PCI_MSIX_PIN(tag, vec) ((tag) | (vec))
438 :
439 : void
440 0 : msix_hwmask(struct pic *pic, int pin)
441 : {
442 0 : }
443 :
444 : void
445 0 : msix_hwunmask(struct pic *pic, int pin)
446 : {
447 0 : }
448 :
449 : void
450 0 : msix_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
451 : {
452 : pci_chipset_tag_t pc = NULL; /* XXX */
453 : bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
454 0 : bus_space_handle_t memh;
455 0 : bus_addr_t base;
456 0 : pcitag_t tag = PCI_MSIX_TAG(pin);
457 0 : int entry = PCI_MSIX_VEC(pin);
458 0 : pcireg_t reg, addr, table;
459 : uint32_t ctrl;
460 : int bir, offset;
461 0 : int off, tblsz;
462 :
463 0 : if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, ®) == 0)
464 0 : panic("%s: no msix capability", __func__);
465 :
466 0 : addr = 0xfee00000UL | (ci->ci_apicid << 12);
467 :
468 0 : table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
469 0 : bir = (table & PCI_MSIX_TABLE_BIR);
470 0 : offset = (table & PCI_MSIX_TABLE_OFF);
471 0 : tblsz = PCI_MSIX_MC_TBLSZ(reg) + 1;
472 :
473 0 : bir = PCI_MAPREG_START + bir * 4;
474 0 : if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
475 0 : _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
476 0 : panic("%s: cannot map registers", __func__);
477 :
478 0 : bus_space_write_8(memt, memh, PCI_MSIX_MA(entry), addr);
479 0 : bus_space_write_4(memt, memh, PCI_MSIX_MD(entry), vec);
480 0 : bus_space_barrier(memt, memh, PCI_MSIX_MA(entry), 16,
481 : BUS_SPACE_BARRIER_WRITE);
482 0 : ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
483 0 : bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
484 : ctrl & ~PCI_MSIX_VC_MASK);
485 :
486 0 : _bus_space_unmap(memt, memh, tblsz * 16, NULL);
487 :
488 0 : pci_conf_write(pc, tag, off, reg | PCI_MSIX_MC_MSIXE);
489 0 : }
490 :
491 : void
492 0 : msix_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
493 : {
494 : pci_chipset_tag_t pc = NULL; /* XXX */
495 : bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
496 0 : bus_space_handle_t memh;
497 0 : bus_addr_t base;
498 0 : pcitag_t tag = PCI_MSIX_TAG(pin);
499 0 : int entry = PCI_MSIX_VEC(pin);
500 0 : pcireg_t reg, table;
501 : uint32_t ctrl;
502 : int bir, offset;
503 0 : int off, tblsz;
504 :
505 0 : if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, ®) == 0)
506 0 : return;
507 :
508 0 : table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
509 0 : bir = (table & PCI_MSIX_TABLE_BIR);
510 0 : offset = (table & PCI_MSIX_TABLE_OFF);
511 0 : tblsz = PCI_MSIX_MC_TBLSZ(reg) + 1;
512 :
513 0 : bir = PCI_MAPREG_START + bir * 4;
514 0 : if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
515 0 : _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
516 0 : panic("%s: cannot map registers", __func__);
517 :
518 0 : ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
519 0 : bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
520 : ctrl | PCI_MSIX_VC_MASK);
521 :
522 0 : _bus_space_unmap(memt, memh, tblsz * 16, NULL);
523 0 : }
524 :
525 : int
526 0 : pci_intr_map_msix(struct pci_attach_args *pa, int vec, pci_intr_handle_t *ihp)
527 : {
528 0 : pci_chipset_tag_t pc = pa->pa_pc;
529 0 : pcitag_t tag = pa->pa_tag;
530 0 : pcireg_t reg;
531 :
532 0 : KASSERT(PCI_MSIX_VEC(vec) == vec);
533 :
534 0 : if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
535 0 : pci_get_capability(pc, tag, PCI_CAP_MSIX, NULL, ®) == 0)
536 0 : return 1;
537 :
538 0 : if (vec > PCI_MSIX_MC_TBLSZ(reg))
539 0 : return 1;
540 :
541 0 : ihp->tag = PCI_MSIX_PIN(tag, vec);
542 0 : ihp->line = APIC_INT_VIA_MSGX;
543 0 : ihp->pin = 0;
544 0 : return 0;
545 0 : }
546 :
547 : int
548 0 : pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
549 : {
550 0 : int pin = pa->pa_rawintrpin;
551 0 : int line = pa->pa_intrline;
552 : #if NIOAPIC > 0
553 : struct mp_intr_map *mip;
554 0 : int bus, dev, func;
555 : #endif
556 :
557 0 : if (pin == 0) {
558 : /* No IRQ used. */
559 : goto bad;
560 : }
561 :
562 0 : if (pin > PCI_INTERRUPT_PIN_MAX) {
563 0 : printf("pci_intr_map: bad interrupt pin %d\n", pin);
564 0 : goto bad;
565 : }
566 :
567 0 : ihp->tag = pa->pa_tag;
568 0 : ihp->line = line;
569 0 : ihp->pin = pin;
570 :
571 : #if NIOAPIC > 0
572 0 : pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
573 :
574 0 : if (mp_busses != NULL) {
575 0 : int mpspec_pin = (dev << 2) | (pin - 1);
576 :
577 0 : if (bus < mp_nbusses) {
578 0 : for (mip = mp_busses[bus].mb_intrs;
579 0 : mip != NULL; mip = mip->next) {
580 0 : if (&mp_busses[bus] == mp_isa_bus ||
581 0 : &mp_busses[bus] == mp_eisa_bus)
582 : continue;
583 0 : if (mip->bus_pin == mpspec_pin) {
584 0 : ihp->line = mip->ioapic_ih | line;
585 0 : return 0;
586 : }
587 : }
588 : }
589 :
590 0 : if (pa->pa_bridgetag) {
591 0 : int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
592 0 : if (pa->pa_bridgeih[swizpin - 1].line != -1) {
593 : ihp->line = pa->pa_bridgeih[swizpin - 1].line;
594 0 : ihp->line |= line;
595 0 : return 0;
596 : }
597 0 : }
598 : /*
599 : * No explicit PCI mapping found. This is not fatal,
600 : * we'll try the ISA (or possibly EISA) mappings next.
601 : */
602 0 : }
603 : #endif
604 :
605 : /*
606 : * Section 6.2.4, `Miscellaneous Functions', says that 255 means
607 : * `unknown' or `no connection' on a PC. We assume that a device with
608 : * `no connection' either doesn't have an interrupt (in which case the
609 : * pin number should be 0, and would have been noticed above), or
610 : * wasn't configured by the BIOS (in which case we punt, since there's
611 : * no real way we can know how the interrupt lines are mapped in the
612 : * hardware).
613 : *
614 : * XXX
615 : * Since IRQ 0 is only used by the clock, and we can't actually be sure
616 : * that the BIOS did its job, we also recognize that as meaning that
617 : * the BIOS has not configured the device.
618 : */
619 0 : if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
620 : goto bad;
621 :
622 0 : if (line >= NUM_LEGACY_IRQS) {
623 0 : printf("pci_intr_map: bad interrupt line %d\n", line);
624 0 : goto bad;
625 : }
626 0 : if (line == 2) {
627 0 : printf("pci_intr_map: changed line 2 to line 9\n");
628 : line = 9;
629 0 : }
630 :
631 : #if NIOAPIC > 0
632 0 : if (mp_busses != NULL) {
633 0 : if (mip == NULL && mp_isa_bus) {
634 0 : for (mip = mp_isa_bus->mb_intrs; mip != NULL;
635 0 : mip = mip->next) {
636 0 : if (mip->bus_pin == line) {
637 0 : ihp->line = mip->ioapic_ih | line;
638 0 : return 0;
639 : }
640 : }
641 : }
642 : #if NEISA > 0
643 : if (mip == NULL && mp_eisa_bus) {
644 : for (mip = mp_eisa_bus->mb_intrs; mip != NULL;
645 : mip = mip->next) {
646 : if (mip->bus_pin == line) {
647 : ihp->line = mip->ioapic_ih | line;
648 : return 0;
649 : }
650 : }
651 : }
652 : #endif
653 0 : if (mip == NULL) {
654 0 : printf("pci_intr_map: "
655 : "bus %d dev %d func %d pin %d; line %d\n",
656 0 : bus, dev, func, pin, line);
657 0 : printf("pci_intr_map: no MP mapping found\n");
658 0 : }
659 : }
660 : #endif
661 :
662 0 : return 0;
663 :
664 : bad:
665 0 : ihp->line = -1;
666 0 : return 1;
667 0 : }
668 :
669 : const char *
670 0 : pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
671 : {
672 : static char irqstr[64];
673 :
674 0 : if (ih.line == 0)
675 0 : panic("pci_intr_string: bogus handle 0x%x", ih.line);
676 :
677 0 : if (ih.line & APIC_INT_VIA_MSG)
678 0 : return ("msi");
679 0 : if (ih.line & APIC_INT_VIA_MSGX)
680 0 : return ("msix");
681 :
682 : #if NIOAPIC > 0
683 0 : if (ih.line & APIC_INT_VIA_APIC)
684 0 : snprintf(irqstr, sizeof(irqstr), "apic %d int %d",
685 0 : APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line));
686 : else
687 0 : snprintf(irqstr, sizeof(irqstr), "irq %d",
688 0 : pci_intr_line(pc, ih));
689 : #else
690 : snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(pc, ih));
691 : #endif
692 0 : return (irqstr);
693 0 : }
694 :
695 : #include "acpiprt.h"
696 : #if NACPIPRT > 0
697 : void acpiprt_route_interrupt(int bus, int dev, int pin);
698 : #endif
699 :
700 : void *
701 0 : pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
702 : int (*func)(void *), void *arg, const char *what)
703 : {
704 : int pin, irq;
705 0 : int bus, dev;
706 0 : pcitag_t tag = ih.tag;
707 : struct pic *pic;
708 :
709 0 : if (ih.line & APIC_INT_VIA_MSG) {
710 0 : return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
711 : func, arg, what);
712 : }
713 0 : if (ih.line & APIC_INT_VIA_MSGX) {
714 0 : return intr_establish(-1, &msix_pic, tag, IST_PULSE, level,
715 : func, arg, what);
716 : }
717 :
718 0 : pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
719 : #if NACPIPRT > 0
720 0 : acpiprt_route_interrupt(bus, dev, ih.pin);
721 : #endif
722 :
723 : pic = &i8259_pic;
724 : pin = irq = ih.line;
725 :
726 : #if NIOAPIC > 0
727 0 : if (ih.line & APIC_INT_VIA_APIC) {
728 0 : pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
729 0 : if (pic == NULL) {
730 0 : printf("pci_intr_establish: bad ioapic %d\n",
731 : APIC_IRQ_APIC(ih.line));
732 0 : return NULL;
733 : }
734 0 : pin = APIC_IRQ_PIN(ih.line);
735 0 : irq = APIC_IRQ_LEGACY_IRQ(ih.line);
736 0 : if (irq < 0 || irq >= NUM_LEGACY_IRQS)
737 : irq = -1;
738 : }
739 : #endif
740 :
741 0 : return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
742 0 : }
743 :
744 : void
745 0 : pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
746 : {
747 0 : intr_disestablish(cookie);
748 0 : }
749 :
750 : struct extent *pciio_ex;
751 : struct extent *pcimem_ex;
752 : struct extent *pcibus_ex;
753 :
754 : void
755 0 : pci_init_extents(void)
756 : {
757 : bios_memmap_t *bmp;
758 : u_int64_t size;
759 :
760 0 : if (pciio_ex == NULL) {
761 : /*
762 : * We only have 64K of addressable I/O space.
763 : * However, since BARs may contain garbage, we cover
764 : * the full 32-bit address space defined by PCI of
765 : * which we only make the first 64K available.
766 : */
767 0 : pciio_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF,
768 : NULL, 0, EX_NOWAIT | EX_FILLED);
769 0 : if (pciio_ex == NULL)
770 0 : return;
771 0 : extent_free(pciio_ex, 0, 0x10000, EX_NOWAIT);
772 0 : }
773 :
774 0 : if (pcimem_ex == NULL) {
775 : /*
776 : * Cover the 36-bit address space addressable by PAE
777 : * here. As long as vendors continue to support
778 : * 32-bit operating systems, we should never see BARs
779 : * outside that region.
780 : *
781 : * Dell 13G servers have important devices outside the
782 : * 36-bit address space. Until we can extract the address
783 : * ranges from ACPI, expand the allowed range to suit.
784 : */
785 0 : pcimem_ex = extent_create("pcimem", 0, 0xffffffffffffffffUL,
786 : M_DEVBUF, NULL, 0, EX_NOWAIT);
787 0 : if (pcimem_ex == NULL)
788 0 : return;
789 0 : extent_alloc_region(pcimem_ex, 0x40000000000UL,
790 : 0xfffffc0000000000UL, EX_NOWAIT);
791 :
792 0 : for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
793 : /*
794 : * Ignore address space beyond 4G.
795 : */
796 0 : if (bmp->addr >= 0x100000000ULL)
797 : continue;
798 0 : size = bmp->size;
799 0 : if (bmp->addr + size >= 0x100000000ULL)
800 0 : size = 0x100000000ULL - bmp->addr;
801 :
802 : /* Ignore zero-sized regions. */
803 0 : if (size == 0)
804 : continue;
805 :
806 0 : if (extent_alloc_region(pcimem_ex, bmp->addr, size,
807 : EX_NOWAIT))
808 0 : printf("memory map conflict 0x%llx/0x%llx\n",
809 0 : bmp->addr, bmp->size);
810 : }
811 :
812 : /* Take out the video buffer area and BIOS areas. */
813 0 : extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE,
814 : EX_CONFLICTOK | EX_NOWAIT);
815 0 : }
816 :
817 0 : if (pcibus_ex == NULL) {
818 0 : pcibus_ex = extent_create("pcibus", 0, 0xff, M_DEVBUF,
819 : NULL, 0, EX_NOWAIT);
820 0 : }
821 0 : }
822 :
823 : #include "acpi.h"
824 : #if NACPI > 0
825 : void acpi_pci_match(struct device *, struct pci_attach_args *);
826 : pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
827 : void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
828 : #endif
829 :
830 : void
831 0 : pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
832 : {
833 : #if NACPI > 0
834 0 : acpi_pci_match(dev, pa);
835 : #endif
836 0 : }
837 :
838 : pcireg_t
839 0 : pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
840 : {
841 : #if NACPI > 0
842 0 : return acpi_pci_min_powerstate(pc, tag);
843 : #else
844 : return pci_get_powerstate(pc, tag);
845 : #endif
846 : }
847 :
848 : void
849 0 : pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
850 : {
851 : #if NACPI > 0
852 0 : acpi_pci_set_powerstate(pc, tag, state, pre);
853 : #endif
854 0 : }
|