xref: /openbsd-src/sys/arch/amd64/pci/pci_machdep.c (revision 4c1e55dc91edd6e69ccc60ce855900fbc12cf34f)
1 /*	$OpenBSD: pci_machdep.c,v 1.53 2011/10/29 19:17:30 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/types.h>
69 #include <sys/param.h>
70 #include <sys/time.h>
71 #include <sys/systm.h>
72 #include <sys/errno.h>
73 #include <sys/device.h>
74 #include <sys/extent.h>
75 #include <sys/malloc.h>
76 
77 #include <uvm/uvm_extern.h>
78 
79 #include <machine/bus.h>
80 
81 #include <machine/pio.h>
82 #include <machine/intr.h>
83 #include <machine/biosvar.h>
84 
85 #include <dev/isa/isareg.h>
86 #include <dev/isa/isavar.h>
87 #include <dev/pci/pcivar.h>
88 #include <dev/pci/pcireg.h>
89 #include <dev/pci/pcidevs.h>
90 #include <dev/pci/ppbreg.h>
91 
92 #include "ioapic.h"
93 
94 #if NIOAPIC > 0
95 #include <machine/i82093var.h>
96 #include <machine/mpbiosvar.h>
97 #endif
98 
99 /*
100  * Memory Mapped Configuration space access.
101  *
102  * Since mapping the whole configuration space will cost us up to
103  * 256MB of kernel virtual memory, we use seperate mappings per bus.
104  * The mappings are created on-demand, such that we only use kernel
105  * virtual memory for busses that are actually present.
106  */
107 bus_addr_t pci_mcfg_addr;
108 int pci_mcfg_min_bus, pci_mcfg_max_bus;
109 bus_space_tag_t pci_mcfgt = X86_BUS_SPACE_MEM;
110 bus_space_handle_t pci_mcfgh[256];
111 void pci_mcfg_map_bus(int);
112 
113 struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
114 
115 #define	PCI_CONF_LOCK()						\
116 do {									\
117 	mtx_enter(&pci_conf_lock);					\
118 } while (0)
119 
120 #define	PCI_CONF_UNLOCK()						\
121 do {									\
122 	mtx_leave(&pci_conf_lock);					\
123 } while (0)
124 
125 #define	PCI_MODE1_ENABLE	0x80000000UL
126 #define	PCI_MODE1_ADDRESS_REG	0x0cf8
127 #define	PCI_MODE1_DATA_REG	0x0cfc
128 
129 /*
130  * PCI doesn't have any special needs; just use the generic versions
131  * of these functions.
132  */
133 struct bus_dma_tag pci_bus_dma_tag = {
134 	NULL,			/* _may_bounce */
135 	_bus_dmamap_create,
136 	_bus_dmamap_destroy,
137 	_bus_dmamap_load,
138 	_bus_dmamap_load_mbuf,
139 	_bus_dmamap_load_uio,
140 	_bus_dmamap_load_raw,
141 	_bus_dmamap_unload,
142 	_bus_dmamap_sync,
143 	_bus_dmamem_alloc,
144 	_bus_dmamem_free,
145 	_bus_dmamem_map,
146 	_bus_dmamem_unmap,
147 	_bus_dmamem_mmap,
148 };
149 
150 void
151 pci_attach_hook(struct device *parent, struct device *self,
152     struct pcibus_attach_args *pba)
153 {
154 	pci_chipset_tag_t pc = pba->pba_pc;
155 	pcitag_t tag;
156 	pcireg_t id, class;
157 
158 	if (pba->pba_bus != 0)
159 		return;
160 
161 	/*
162 	 * In order to decide whether the system supports MSI we look
163 	 * at the host bridge, which should be device 0 function 0 on
164 	 * bus 0.  It is better to not enable MSI on systems that
165 	 * support it than the other way around, so be conservative
166 	 * here.  So we don't enable MSI if we don't find a host
167 	 * bridge there.  We also deliberately don't enable MSI on
168 	 * chipsets from low-end manifacturers like VIA and SiS.
169 	 */
170 	tag = pci_make_tag(pc, 0, 0, 0);
171 	id = pci_conf_read(pc, tag, PCI_ID_REG);
172 	class = pci_conf_read(pc, tag, PCI_CLASS_REG);
173 
174 	if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
175 	    PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST)
176 		return;
177 
178 	switch (PCI_VENDOR(id)) {
179 	case PCI_VENDOR_INTEL:
180 		/*
181 		 * In the wonderful world of virtualization you can
182 		 * have the latest 64-bit AMD multicore CPU behind a
183 		 * prehistoric Intel host bridge.  Give them what they
184 		 * deserve.
185 		 */
186 		switch (PCI_PRODUCT(id)) {
187 		case PCI_PRODUCT_INTEL_82441FX:	/* QEMU */
188 		case PCI_PRODUCT_INTEL_82443BX:	/* VMWare */
189 			break;
190 		default:
191 			pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
192 			break;
193 		}
194 		break;
195 	case PCI_VENDOR_NVIDIA:
196 	case PCI_VENDOR_AMD:
197 		pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
198 		break;
199 	}
200 
201 	/*
202 	 * Don't enable MSI on a HyperTransport bus.  In order to
203 	 * determine that bus 0 is a HyperTransport bus, we look at
204 	 * device 24 function 0, which is the HyperTransport
205 	 * host/primary interface integrated on most 64-bit AMD CPUs.
206 	 * If that device has a HyperTransport capability, bus 0 must
207 	 * be a HyperTransport bus and we disable MSI.
208 	 */
209 	tag = pci_make_tag(pc, 0, 24, 0);
210 	if (pci_get_capability(pc, tag, PCI_CAP_HT, NULL, NULL))
211 		pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
212 }
213 
214 int
215 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
216 {
217 	return (32);
218 }
219 
220 pcitag_t
221 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
222 {
223 	if (bus >= 256 || device >= 32 || function >= 8)
224 		panic("pci_make_tag: bad request");
225 
226 	return (PCI_MODE1_ENABLE |
227 	    (bus << 16) | (device << 11) | (function << 8));
228 }
229 
230 void
231 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
232 {
233 	if (bp != NULL)
234 		*bp = (tag >> 16) & 0xff;
235 	if (dp != NULL)
236 		*dp = (tag >> 11) & 0x1f;
237 	if (fp != NULL)
238 		*fp = (tag >> 8) & 0x7;
239 }
240 
241 int
242 pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
243 {
244 	int bus;
245 
246 	if (pci_mcfg_addr) {
247 		pci_decompose_tag(pc, tag, &bus, NULL, NULL);
248 		if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
249 			return PCIE_CONFIG_SPACE_SIZE;
250 	}
251 
252 	return PCI_CONFIG_SPACE_SIZE;
253 }
254 
255 void
256 pci_mcfg_map_bus(int bus)
257 {
258 	if (pci_mcfgh[bus])
259 		return;
260 
261 	if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
262 	    0, &pci_mcfgh[bus]))
263 		panic("pci_conf_read: cannot map mcfg space");
264 }
265 
266 pcireg_t
267 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
268 {
269 	pcireg_t data;
270 	int bus;
271 
272 	KASSERT((reg & 0x3) == 0);
273 
274 	if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
275 		pci_decompose_tag(pc, tag, &bus, NULL, NULL);
276 		if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
277 			pci_mcfg_map_bus(bus);
278 			data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
279 			    (tag & 0x000ff00) << 4 | reg);
280 			return data;
281 		}
282 	}
283 
284 	PCI_CONF_LOCK();
285 	outl(PCI_MODE1_ADDRESS_REG, tag | reg);
286 	data = inl(PCI_MODE1_DATA_REG);
287 	outl(PCI_MODE1_ADDRESS_REG, 0);
288 	PCI_CONF_UNLOCK();
289 
290 	return data;
291 }
292 
293 void
294 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
295 {
296 	int bus;
297 
298 	KASSERT((reg & 0x3) == 0);
299 
300 	if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
301 		pci_decompose_tag(pc, tag, &bus, NULL, NULL);
302 		if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
303 			pci_mcfg_map_bus(bus);
304 			bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
305 			    (tag & 0x000ff00) << 4 | reg, data);
306 			return;
307 		}
308 	}
309 
310 	PCI_CONF_LOCK();
311 	outl(PCI_MODE1_ADDRESS_REG, tag | reg);
312 	outl(PCI_MODE1_DATA_REG, data);
313 	outl(PCI_MODE1_ADDRESS_REG, 0);
314 	PCI_CONF_UNLOCK();
315 }
316 
317 void msi_hwmask(struct pic *, int);
318 void msi_hwunmask(struct pic *, int);
319 void msi_addroute(struct pic *, struct cpu_info *, int, int, int);
320 void msi_delroute(struct pic *, struct cpu_info *, int, int, int);
321 
322 struct pic msi_pic = {
323 	{0, {NULL}, NULL, 0, "msi", NULL, 0, 0},
324 	PIC_MSI,
325 #ifdef MULTIPROCESSOR
326 	{},
327 #endif
328 	msi_hwmask,
329 	msi_hwunmask,
330 	msi_addroute,
331 	msi_delroute,
332 	NULL,
333 	ioapic_edge_stubs
334 };
335 
336 void
337 msi_hwmask(struct pic *pic, int pin)
338 {
339 }
340 
341 void
342 msi_hwunmask(struct pic *pic, int pin)
343 {
344 }
345 
346 void
347 msi_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
348 {
349 	pci_chipset_tag_t pc = NULL; /* XXX */
350 	pcitag_t tag = pin;
351 	pcireg_t reg, addr;
352 	int off;
353 
354 	if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, &reg) == 0)
355 		panic("%s: no msi capability", __func__);
356 
357 	addr = 0xfee00000UL | (ci->ci_apicid << 12);
358 
359 	if (reg & PCI_MSI_MC_C64) {
360 		pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
361 		pci_conf_write(pc, tag, off + PCI_MSI_MAU32, 0);
362 		pci_conf_write(pc, tag, off + PCI_MSI_MD64, vec);
363 	} else {
364 		pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
365 		pci_conf_write(pc, tag, off + PCI_MSI_MD32, vec);
366 	}
367 	pci_conf_write(pc, tag, off, reg | PCI_MSI_MC_MSIE);
368 }
369 
370 void
371 msi_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
372 {
373 	pci_chipset_tag_t pc = NULL; /* XXX */
374 	pcitag_t tag = pin;
375 	pcireg_t reg;
376 	int off;
377 
378 	if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, &reg) == 0)
379 		panic("%s: no msi capability", __func__);
380 	pci_conf_write(pc, tag, off, reg & ~PCI_MSI_MC_MSIE);
381 }
382 
383 int
384 pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
385 {
386 	pci_chipset_tag_t pc = pa->pa_pc;
387 	pcitag_t tag = pa->pa_tag;
388 
389 	if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
390 	    pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
391 		return 1;
392 
393 	ihp->tag = tag;
394 	ihp->line = APIC_INT_VIA_MSG;
395 	ihp->pin = 0;
396 	return 0;
397 }
398 
399 int
400 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
401 {
402 	int pin = pa->pa_rawintrpin;
403 	int line = pa->pa_intrline;
404 #if NIOAPIC > 0
405 	struct mp_intr_map *mip;
406 	int bus, dev, func;
407 #endif
408 
409 	if (pin == 0) {
410 		/* No IRQ used. */
411 		goto bad;
412 	}
413 
414 	if (pin > PCI_INTERRUPT_PIN_MAX) {
415 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
416 		goto bad;
417 	}
418 
419 	ihp->tag = pa->pa_tag;
420 	ihp->line = line;
421 	ihp->pin = pin;
422 
423 #if NIOAPIC > 0
424 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
425 
426 	if (mp_busses != NULL) {
427 		int mpspec_pin = (dev << 2) | (pin - 1);
428 
429 		if (bus < mp_nbusses) {
430 			for (mip = mp_busses[bus].mb_intrs;
431 			     mip != NULL; mip = mip->next) {
432 				if (&mp_busses[bus] == mp_isa_bus ||
433 				    &mp_busses[bus] == mp_eisa_bus)
434 					continue;
435 				if (mip->bus_pin == mpspec_pin) {
436 					ihp->line = mip->ioapic_ih | line;
437 					return 0;
438 				}
439 			}
440 		}
441 
442 		if (pa->pa_bridgetag) {
443 			int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
444 			if (pa->pa_bridgeih[swizpin - 1].line != -1) {
445 				ihp->line = pa->pa_bridgeih[swizpin - 1].line;
446 				ihp->line |= line;
447 				return 0;
448 			}
449 		}
450 		/*
451 		 * No explicit PCI mapping found. This is not fatal,
452 		 * we'll try the ISA (or possibly EISA) mappings next.
453 		 */
454 	}
455 #endif
456 
457 	/*
458 	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
459 	 * `unknown' or `no connection' on a PC.  We assume that a device with
460 	 * `no connection' either doesn't have an interrupt (in which case the
461 	 * pin number should be 0, and would have been noticed above), or
462 	 * wasn't configured by the BIOS (in which case we punt, since there's
463 	 * no real way we can know how the interrupt lines are mapped in the
464 	 * hardware).
465 	 *
466 	 * XXX
467 	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
468 	 * that the BIOS did its job, we also recognize that as meaning that
469 	 * the BIOS has not configured the device.
470 	 */
471 	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
472 		goto bad;
473 
474 	if (line >= NUM_LEGACY_IRQS) {
475 		printf("pci_intr_map: bad interrupt line %d\n", line);
476 		goto bad;
477 	}
478 	if (line == 2) {
479 		printf("pci_intr_map: changed line 2 to line 9\n");
480 		line = 9;
481 	}
482 
483 #if NIOAPIC > 0
484 	if (mp_busses != NULL) {
485 		if (mip == NULL && mp_isa_bus) {
486 			for (mip = mp_isa_bus->mb_intrs; mip != NULL;
487 			    mip = mip->next) {
488 				if (mip->bus_pin == line) {
489 					ihp->line = mip->ioapic_ih | line;
490 					return 0;
491 				}
492 			}
493 		}
494 #if NEISA > 0
495 		if (mip == NULL && mp_eisa_bus) {
496 			for (mip = mp_eisa_bus->mb_intrs;  mip != NULL;
497 			    mip = mip->next) {
498 				if (mip->bus_pin == line) {
499 					ihp->line = mip->ioapic_ih | line;
500 					return 0;
501 				}
502 			}
503 		}
504 #endif
505 		if (mip == NULL) {
506 			printf("pci_intr_map: "
507 			    "bus %d dev %d func %d pin %d; line %d\n",
508 			    bus, dev, func, pin, line);
509 			printf("pci_intr_map: no MP mapping found\n");
510 		}
511 	}
512 #endif
513 
514 	return 0;
515 
516 bad:
517 	ihp->line = -1;
518 	return 1;
519 }
520 
521 const char *
522 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
523 {
524 	static char irqstr[64];
525 
526 	if (ih.line == 0)
527 		panic("pci_intr_string: bogus handle 0x%x", ih.line);
528 
529 	if (ih.line & APIC_INT_VIA_MSG)
530 		return ("msi");
531 
532 #if NIOAPIC > 0
533 	if (ih.line & APIC_INT_VIA_APIC)
534 		snprintf(irqstr, sizeof(irqstr), "apic %d int %d",
535 		    APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line));
536 	else
537 		snprintf(irqstr, sizeof(irqstr), "irq %d",
538 		    pci_intr_line(pc, ih));
539 #else
540 	snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(pc, ih));
541 #endif
542 	return (irqstr);
543 }
544 
545 #include "acpiprt.h"
546 #if NACPIPRT > 0
547 void	acpiprt_route_interrupt(int bus, int dev, int pin);
548 #endif
549 
550 void *
551 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
552     int (*func)(void *), void *arg, const char *what)
553 {
554 	int pin, irq;
555 	int bus, dev;
556 	pcitag_t tag = ih.tag;
557 	struct pic *pic;
558 
559 	if (ih.line & APIC_INT_VIA_MSG) {
560 		return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
561 		    func, arg, what);
562 	}
563 
564 	pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
565 #if NACPIPRT > 0
566 	acpiprt_route_interrupt(bus, dev, ih.pin);
567 #endif
568 
569 	pic = &i8259_pic;
570 	pin = irq = ih.line;
571 
572 #if NIOAPIC > 0
573 	if (ih.line & APIC_INT_VIA_APIC) {
574 		pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
575 		if (pic == NULL) {
576 			printf("pci_intr_establish: bad ioapic %d\n",
577 			    APIC_IRQ_APIC(ih.line));
578 			return NULL;
579 		}
580 		pin = APIC_IRQ_PIN(ih.line);
581 		irq = APIC_IRQ_LEGACY_IRQ(ih.line);
582 		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
583 			irq = -1;
584 	}
585 #endif
586 
587 	return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
588 }
589 
590 void
591 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
592 {
593 	intr_disestablish(cookie);
594 }
595 
596 struct extent *pciio_ex;
597 struct extent *pcimem_ex;
598 
599 void
600 pci_init_extents(void)
601 {
602 	bios_memmap_t *bmp;
603 	u_int64_t size;
604 
605 	if (pciio_ex == NULL) {
606 		/*
607 		 * We only have 64K of addressable I/O space.
608 		 * However, since BARs may contain garbage, we cover
609 		 * the full 32-bit address space defined by PCI of
610 		 * which we only make the first 64K available.
611 		 */
612 		pciio_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF,
613 		    NULL, 0, EX_NOWAIT | EX_FILLED);
614 		if (pciio_ex == NULL)
615 			return;
616 		extent_free(pciio_ex, 0, 0x10000, M_NOWAIT);
617 	}
618 
619 	if (pcimem_ex == NULL) {
620 		/*
621 		 * Cover the 36-bit address space addressable by PAE
622 		 * here.  As long as vendors continue to support
623 		 * 32-bit operating systems, we should never see BARs
624 		 * outside that region.
625 		 */
626 		pcimem_ex = extent_create("pcimem", 0, 0xfffffffff, M_DEVBUF,
627 		    NULL, 0, EX_NOWAIT);
628 		if (pcimem_ex == NULL)
629 			return;
630 
631 		for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
632 			/*
633 			 * Ignore address space beyond 4G.
634 			 */
635 			if (bmp->addr >= 0x100000000ULL)
636 				continue;
637 			size = bmp->size;
638 			if (bmp->addr + size >= 0x100000000ULL)
639 				size = 0x100000000ULL - bmp->addr;
640 
641 			/* Ignore zero-sized regions. */
642 			if (size == 0)
643 				continue;
644 
645 			if (extent_alloc_region(pcimem_ex, bmp->addr, size,
646 			    EX_NOWAIT))
647 				printf("memory map conflict 0x%llx/0x%llx\n",
648 				    bmp->addr, bmp->size);
649 		}
650 
651 		/* Take out the video buffer area and BIOS areas. */
652 		extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE,
653 		    EX_CONFLICTOK | EX_NOWAIT);
654 	}
655 }
656 
657 #include "acpi.h"
658 #if NACPI > 0
659 void acpi_pci_match(struct device *, struct pci_attach_args *);
660 #endif
661 
662 void
663 pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
664 {
665 #if NACPI > 0
666 	acpi_pci_match(dev, pa);
667 #endif
668 }
669