xref: /openbsd-src/sys/arch/amd64/pci/pci_machdep.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /*	$OpenBSD: pci_machdep.c,v 1.59 2014/04/19 11:53:42 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))
379 		pci_conf_write(pc, tag, off, reg & ~PCI_MSI_MC_MSIE);
380 }
381 
382 int
383 pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
384 {
385 	pci_chipset_tag_t pc = pa->pa_pc;
386 	pcitag_t tag = pa->pa_tag;
387 
388 	if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
389 	    pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
390 		return 1;
391 
392 	ihp->tag = tag;
393 	ihp->line = APIC_INT_VIA_MSG;
394 	ihp->pin = 0;
395 	return 0;
396 }
397 
398 int
399 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
400 {
401 	int pin = pa->pa_rawintrpin;
402 	int line = pa->pa_intrline;
403 #if NIOAPIC > 0
404 	struct mp_intr_map *mip;
405 	int bus, dev, func;
406 #endif
407 
408 	if (pin == 0) {
409 		/* No IRQ used. */
410 		goto bad;
411 	}
412 
413 	if (pin > PCI_INTERRUPT_PIN_MAX) {
414 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
415 		goto bad;
416 	}
417 
418 	ihp->tag = pa->pa_tag;
419 	ihp->line = line;
420 	ihp->pin = pin;
421 
422 #if NIOAPIC > 0
423 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
424 
425 	if (mp_busses != NULL) {
426 		int mpspec_pin = (dev << 2) | (pin - 1);
427 
428 		if (bus < mp_nbusses) {
429 			for (mip = mp_busses[bus].mb_intrs;
430 			     mip != NULL; mip = mip->next) {
431 				if (&mp_busses[bus] == mp_isa_bus ||
432 				    &mp_busses[bus] == mp_eisa_bus)
433 					continue;
434 				if (mip->bus_pin == mpspec_pin) {
435 					ihp->line = mip->ioapic_ih | line;
436 					return 0;
437 				}
438 			}
439 		}
440 
441 		if (pa->pa_bridgetag) {
442 			int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
443 			if (pa->pa_bridgeih[swizpin - 1].line != -1) {
444 				ihp->line = pa->pa_bridgeih[swizpin - 1].line;
445 				ihp->line |= line;
446 				return 0;
447 			}
448 		}
449 		/*
450 		 * No explicit PCI mapping found. This is not fatal,
451 		 * we'll try the ISA (or possibly EISA) mappings next.
452 		 */
453 	}
454 #endif
455 
456 	/*
457 	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
458 	 * `unknown' or `no connection' on a PC.  We assume that a device with
459 	 * `no connection' either doesn't have an interrupt (in which case the
460 	 * pin number should be 0, and would have been noticed above), or
461 	 * wasn't configured by the BIOS (in which case we punt, since there's
462 	 * no real way we can know how the interrupt lines are mapped in the
463 	 * hardware).
464 	 *
465 	 * XXX
466 	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
467 	 * that the BIOS did its job, we also recognize that as meaning that
468 	 * the BIOS has not configured the device.
469 	 */
470 	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
471 		goto bad;
472 
473 	if (line >= NUM_LEGACY_IRQS) {
474 		printf("pci_intr_map: bad interrupt line %d\n", line);
475 		goto bad;
476 	}
477 	if (line == 2) {
478 		printf("pci_intr_map: changed line 2 to line 9\n");
479 		line = 9;
480 	}
481 
482 #if NIOAPIC > 0
483 	if (mp_busses != NULL) {
484 		if (mip == NULL && mp_isa_bus) {
485 			for (mip = mp_isa_bus->mb_intrs; mip != NULL;
486 			    mip = mip->next) {
487 				if (mip->bus_pin == line) {
488 					ihp->line = mip->ioapic_ih | line;
489 					return 0;
490 				}
491 			}
492 		}
493 #if NEISA > 0
494 		if (mip == NULL && mp_eisa_bus) {
495 			for (mip = mp_eisa_bus->mb_intrs;  mip != NULL;
496 			    mip = mip->next) {
497 				if (mip->bus_pin == line) {
498 					ihp->line = mip->ioapic_ih | line;
499 					return 0;
500 				}
501 			}
502 		}
503 #endif
504 		if (mip == NULL) {
505 			printf("pci_intr_map: "
506 			    "bus %d dev %d func %d pin %d; line %d\n",
507 			    bus, dev, func, pin, line);
508 			printf("pci_intr_map: no MP mapping found\n");
509 		}
510 	}
511 #endif
512 
513 	return 0;
514 
515 bad:
516 	ihp->line = -1;
517 	return 1;
518 }
519 
520 const char *
521 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
522 {
523 	static char irqstr[64];
524 
525 	if (ih.line == 0)
526 		panic("pci_intr_string: bogus handle 0x%x", ih.line);
527 
528 	if (ih.line & APIC_INT_VIA_MSG)
529 		return ("msi");
530 
531 #if NIOAPIC > 0
532 	if (ih.line & APIC_INT_VIA_APIC)
533 		snprintf(irqstr, sizeof(irqstr), "apic %d int %d",
534 		    APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line));
535 	else
536 		snprintf(irqstr, sizeof(irqstr), "irq %d",
537 		    pci_intr_line(pc, ih));
538 #else
539 	snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(pc, ih));
540 #endif
541 	return (irqstr);
542 }
543 
544 #include "acpiprt.h"
545 #if NACPIPRT > 0
546 void	acpiprt_route_interrupt(int bus, int dev, int pin);
547 #endif
548 
549 void *
550 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
551     int (*func)(void *), void *arg, const char *what)
552 {
553 	int pin, irq;
554 	int bus, dev;
555 	pcitag_t tag = ih.tag;
556 	struct pic *pic;
557 
558 	if (ih.line & APIC_INT_VIA_MSG) {
559 		return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
560 		    func, arg, what);
561 	}
562 
563 	pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
564 #if NACPIPRT > 0
565 	acpiprt_route_interrupt(bus, dev, ih.pin);
566 #endif
567 
568 	pic = &i8259_pic;
569 	pin = irq = ih.line;
570 
571 #if NIOAPIC > 0
572 	if (ih.line & APIC_INT_VIA_APIC) {
573 		pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
574 		if (pic == NULL) {
575 			printf("pci_intr_establish: bad ioapic %d\n",
576 			    APIC_IRQ_APIC(ih.line));
577 			return NULL;
578 		}
579 		pin = APIC_IRQ_PIN(ih.line);
580 		irq = APIC_IRQ_LEGACY_IRQ(ih.line);
581 		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
582 			irq = -1;
583 	}
584 #endif
585 
586 	return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
587 }
588 
589 void
590 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
591 {
592 	intr_disestablish(cookie);
593 }
594 
595 struct extent *pciio_ex;
596 struct extent *pcimem_ex;
597 struct extent *pcibus_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, 0xffffffffffffffffUL,
627 		    M_DEVBUF, NULL, 0, EX_NOWAIT);
628 		if (pcimem_ex == NULL)
629 			return;
630 		extent_alloc_region(pcimem_ex, 0x1000000000UL,
631 		    0xfffffff000000000UL, EX_NOWAIT);
632 
633 		for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
634 			/*
635 			 * Ignore address space beyond 4G.
636 			 */
637 			if (bmp->addr >= 0x100000000ULL)
638 				continue;
639 			size = bmp->size;
640 			if (bmp->addr + size >= 0x100000000ULL)
641 				size = 0x100000000ULL - bmp->addr;
642 
643 			/* Ignore zero-sized regions. */
644 			if (size == 0)
645 				continue;
646 
647 			if (extent_alloc_region(pcimem_ex, bmp->addr, size,
648 			    EX_NOWAIT))
649 				printf("memory map conflict 0x%llx/0x%llx\n",
650 				    bmp->addr, bmp->size);
651 		}
652 
653 		/* Take out the video buffer area and BIOS areas. */
654 		extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE,
655 		    EX_CONFLICTOK | EX_NOWAIT);
656 	}
657 
658 	if (pcibus_ex == NULL) {
659 		pcibus_ex = extent_create("pcibus", 0, 0xff, M_DEVBUF,
660 		    NULL, 0, EX_NOWAIT);
661 	}
662 }
663 
664 #include "acpi.h"
665 #if NACPI > 0
666 void acpi_pci_match(struct device *, struct pci_attach_args *);
667 pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
668 void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
669 #endif
670 
671 void
672 pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
673 {
674 #if NACPI > 0
675 	acpi_pci_match(dev, pa);
676 #endif
677 }
678 
679 pcireg_t
680 pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
681 {
682 #if NACPI > 0
683 	return acpi_pci_min_powerstate(pc, tag);
684 #else
685 	return pci_get_powerstate(pc, tag);
686 #endif
687 }
688 
689 void
690 pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
691 {
692 #if NACPI > 0
693 	acpi_pci_set_powerstate(pc, tag, state, pre);
694 #endif
695 }
696