xref: /openbsd-src/sys/arch/amd64/pci/pci_machdep.c (revision 2b0358df1d88d06ef4139321dd05bd5e05d91eaf)
1 /*	$OpenBSD: pci_machdep.c,v 1.24 2009/04/04 16:03:17 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  * On PCs, there are two methods of generating PCI configuration cycles.
68  * We try to detect the appropriate mechanism for this machine and set
69  * up a few function pointers to access the correct method directly.
70  *
71  * The configuration method can be hard-coded in the config file by
72  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
73  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
74  */
75 
76 #include <sys/types.h>
77 #include <sys/param.h>
78 #include <sys/time.h>
79 #include <sys/systm.h>
80 #include <sys/errno.h>
81 #include <sys/device.h>
82 
83 #include <uvm/uvm_extern.h>
84 
85 #include <machine/bus.h>
86 
87 #include <machine/pio.h>
88 #include <machine/intr.h>
89 
90 #include <dev/isa/isareg.h>
91 #include <dev/isa/isavar.h>
92 #include <dev/pci/pcivar.h>
93 #include <dev/pci/pcireg.h>
94 #include <dev/pci/pcidevs.h>
95 #include <dev/pci/ppbreg.h>
96 
97 #include "ioapic.h"
98 
99 #if NIOAPIC > 0
100 #include <machine/i82093var.h>
101 #include <machine/mpbiosvar.h>
102 #endif
103 
104 int pci_mode = -1;
105 
106 struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
107 
108 #define	PCI_CONF_LOCK()						\
109 do {									\
110 	mtx_enter(&pci_conf_lock);					\
111 } while (0)
112 
113 #define	PCI_CONF_UNLOCK()						\
114 do {									\
115 	mtx_leave(&pci_conf_lock);					\
116 } while (0)
117 
118 #define	PCI_MODE1_ENABLE	0x80000000UL
119 #define	PCI_MODE1_ADDRESS_REG	0x0cf8
120 #define	PCI_MODE1_DATA_REG	0x0cfc
121 
122 #define	PCI_MODE2_ENABLE_REG	0x0cf8
123 #define	PCI_MODE2_FORWARD_REG	0x0cfa
124 
125 #define _m1tag(b, d, f) \
126 	(PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8))
127 #define _qe(bus, dev, fcn, vend, prod) \
128 	{_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
129 struct {
130 	u_int32_t tag;
131 	pcireg_t id;
132 } pcim1_quirk_tbl[] = {
133 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
134 	/* XXX Triflex2 not tested */
135 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
136 	_qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
137 	/* Triton needed for Connectix Virtual PC */
138 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
139 	/* Connectix Virtual PC 5 has a 440BX */
140 	_qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
141 	{0, 0xffffffff} /* patchable */
142 };
143 #undef _m1tag
144 #undef _qe
145 
146 /*
147  * PCI doesn't have any special needs; just use the generic versions
148  * of these functions.
149  */
150 struct bus_dma_tag pci_bus_dma_tag = {
151 	NULL,			/* _may_bounce */
152 	_bus_dmamap_create,
153 	_bus_dmamap_destroy,
154 	_bus_dmamap_load,
155 	_bus_dmamap_load_mbuf,
156 	_bus_dmamap_load_uio,
157 	_bus_dmamap_load_raw,
158 	_bus_dmamap_unload,
159 	NULL,
160 	_bus_dmamem_alloc,
161 	_bus_dmamem_free,
162 	_bus_dmamem_map,
163 	_bus_dmamem_unmap,
164 	_bus_dmamem_mmap,
165 };
166 
167 extern void amdgart_probe(struct pcibus_attach_args *);
168 
169 void
170 pci_attach_hook(struct device *parent, struct device *self,
171     struct pcibus_attach_args *pba)
172 {
173 	if (pba->pba_bus == 0) {
174 		printf(": configuration mode %d", pci_mode);
175 		amdgart_probe(pba);
176 	}
177 }
178 
179 int
180 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
181 {
182 
183 	/*
184 	 * Bus number is irrelevant.  If Configuration Mechanism 2 is in
185 	 * use, can only have devices 0-15 on any bus.  If Configuration
186 	 * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal'
187 	 * range).
188 	 */
189 	if (pci_mode == 2)
190 		return (16);
191 	else
192 		return (32);
193 }
194 
195 pcitag_t
196 pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
197 {
198 	pcitag_t tag;
199 
200 	switch (pci_mode) {
201 	case 1:
202 		if (bus >= 256 || device >= 32 || function >= 8)
203 			panic("pci_make_tag: bad request");
204 
205 		tag.mode1 = PCI_MODE1_ENABLE |
206 		    	(bus << 16) | (device << 11) | (function << 8);
207 		break;
208 	case 2:
209 		if (bus >= 256 || device >= 16 || function >= 8)
210 			panic("pci_make_tag: bad request");
211 
212 		tag.mode2.port = 0xc000 | (device << 8);
213 		tag.mode2.enable = 0xf0 | (function << 1);
214 		tag.mode2.forward = bus;
215 		break;
216 	default:
217 		panic("pci_make_tag: mode not configured");
218 	}
219 
220 	return tag;
221 }
222 
223 void
224 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
225 {
226 
227 	switch (pci_mode) {
228 	case 1:
229 		if (bp != NULL)
230 			*bp = (tag.mode1 >> 16) & 0xff;
231 		if (dp != NULL)
232 			*dp = (tag.mode1 >> 11) & 0x1f;
233 		if (fp != NULL)
234 			*fp = (tag.mode1 >> 8) & 0x7;
235 		break;
236 	case 2:
237 		if (bp != NULL)
238 			*bp = tag.mode2.forward & 0xff;
239 		if (dp != NULL)
240 			*dp = (tag.mode2.port >> 8) & 0xf;
241 		if (fp != NULL)
242 			*fp = (tag.mode2.enable >> 1) & 0x7;
243 		break;
244 	default:
245 		panic("pci_decompose_tag: mode not configured");
246 	}
247 }
248 
249 pcireg_t
250 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
251 {
252 	pcireg_t data;
253 
254 	PCI_CONF_LOCK();
255 	switch (pci_mode) {
256 	case 1:
257 		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
258 		data = inl(PCI_MODE1_DATA_REG);
259 		outl(PCI_MODE1_ADDRESS_REG, 0);
260 		break;
261 	case 2:
262 		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
263 		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
264 		data = inl(tag.mode2.port | reg);
265 		outb(PCI_MODE2_ENABLE_REG, 0);
266 		break;
267 	default:
268 		panic("pci_conf_read: mode not configured");
269 	}
270 	PCI_CONF_UNLOCK();
271 
272 	return data;
273 }
274 
275 void
276 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
277 {
278 
279 	PCI_CONF_LOCK();
280 	switch (pci_mode) {
281 	case 1:
282 		outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg);
283 		outl(PCI_MODE1_DATA_REG, data);
284 		outl(PCI_MODE1_ADDRESS_REG, 0);
285 		break;
286 	case 2:
287 		outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
288 		outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
289 		outl(tag.mode2.port | reg, data);
290 		outb(PCI_MODE2_ENABLE_REG, 0);
291 		break;
292 	default:
293 		panic("pci_conf_write: mode not configured");
294 	}
295 	PCI_CONF_UNLOCK();
296 }
297 
298 int
299 pci_mode_detect(void)
300 {
301 
302 #ifdef PCI_CONF_MODE
303 #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
304 	return (pci_mode = PCI_CONF_MODE);
305 #else
306 #error Invalid PCI configuration mode.
307 #endif
308 #else
309 	u_int32_t sav, val;
310 	int i;
311 	pcireg_t idreg;
312 
313 	if (pci_mode != -1)
314 		return pci_mode;
315 
316 	/*
317 	 * We try to divine which configuration mode the host bridge wants.
318 	 */
319 
320 	sav = inl(PCI_MODE1_ADDRESS_REG);
321 
322 	pci_mode = 1; /* assume this for now */
323 	/*
324 	 * catch some known buggy implementations of mode 1
325 	 */
326 	for (i = 0; i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]);
327 	     i++) {
328 		pcitag_t t;
329 
330 		if (!pcim1_quirk_tbl[i].tag)
331 			break;
332 		t.mode1 = pcim1_quirk_tbl[i].tag;
333 		idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
334 		if (idreg == pcim1_quirk_tbl[i].id) {
335 #ifdef DEBUG
336 			printf("known mode 1 PCI chipset (%08x)\n",
337 			       idreg);
338 #endif
339 			return (pci_mode);
340 		}
341 	}
342 
343 	/*
344 	 * Strong check for standard compliant mode 1:
345 	 * 1. bit 31 ("enable") can be set
346 	 * 2. byte/word access does not affect register
347 	 */
348 	outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
349 	outb(PCI_MODE1_ADDRESS_REG + 3, 0);
350 	outw(PCI_MODE1_ADDRESS_REG + 2, 0);
351 	val = inl(PCI_MODE1_ADDRESS_REG);
352 	if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
353 #ifdef DEBUG
354 		printf("pci_mode_detect: mode 1 enable failed (%x)\n",
355 		       val);
356 #endif
357 		goto not1;
358 	}
359 	outl(PCI_MODE1_ADDRESS_REG, 0);
360 	val = inl(PCI_MODE1_ADDRESS_REG);
361 	if ((val & 0x80fffffc) != 0)
362 		goto not1;
363 	return (pci_mode);
364 not1:
365 	outl(PCI_MODE1_ADDRESS_REG, sav);
366 
367 	/*
368 	 * This mode 2 check is quite weak (and known to give false
369 	 * positives on some Compaq machines).
370 	 * However, this doesn't matter, because this is the
371 	 * last test, and simply no PCI devices will be found if
372 	 * this happens.
373 	 */
374 	outb(PCI_MODE2_ENABLE_REG, 0);
375 	outb(PCI_MODE2_FORWARD_REG, 0);
376 	if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
377 	    inb(PCI_MODE2_FORWARD_REG) != 0)
378 		goto not2;
379 	return (pci_mode = 2);
380 not2:
381 
382 	return (pci_mode = 0);
383 #endif
384 }
385 
386 int
387 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
388 {
389 	int pin = pa->pa_rawintrpin;
390 	int line = pa->pa_intrline;
391 #if NIOAPIC > 0
392 	int bus, dev, func;
393 	int mppin;
394 #endif
395 
396 	if (pin == 0) {
397 		/* No IRQ used. */
398 		goto bad;
399 	}
400 
401 	if (pin > PCI_INTERRUPT_PIN_MAX) {
402 		printf("pci_intr_map: bad interrupt pin %d\n", pin);
403 		goto bad;
404 	}
405 
406 	ihp->tag = pa->pa_tag;
407 	ihp->line = line;
408 	ihp->pin = pin;
409 
410 #if NIOAPIC > 0
411 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
412 	if (mp_busses != NULL) {
413 		mppin = (dev << 2)|(pin - 1);
414 		if (intr_find_mpmapping(bus, mppin, &ihp->line) == 0) {
415 			ihp->line |= line;
416 			return 0;
417 		}
418 		if (pa->pa_bridgetag) {
419 			int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
420 			if (pa->pa_bridgeih[swizpin - 1].line != -1) {
421 				ihp->line = pa->pa_bridgeih[swizpin - 1].line;
422 				ihp->line |= line;
423 				return 0;
424 			}
425 		}
426 		/*
427 		 * No explicit PCI mapping found. This is not fatal,
428 		 * we'll try the ISA (or possibly EISA) mappings next.
429 		 */
430 	}
431 #endif
432 
433 	/*
434 	 * Section 6.2.4, `Miscellaneous Functions', says that 255 means
435 	 * `unknown' or `no connection' on a PC.  We assume that a device with
436 	 * `no connection' either doesn't have an interrupt (in which case the
437 	 * pin number should be 0, and would have been noticed above), or
438 	 * wasn't configured by the BIOS (in which case we punt, since there's
439 	 * no real way we can know how the interrupt lines are mapped in the
440 	 * hardware).
441 	 *
442 	 * XXX
443 	 * Since IRQ 0 is only used by the clock, and we can't actually be sure
444 	 * that the BIOS did its job, we also recognize that as meaning that
445 	 * the BIOS has not configured the device.
446 	 */
447 	if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
448 		goto bad;
449 
450 	if (line >= NUM_LEGACY_IRQS) {
451 		printf("pci_intr_map: bad interrupt line %d\n", line);
452 		goto bad;
453 	}
454 	if (line == 2) {
455 		printf("pci_intr_map: changed line 2 to line 9\n");
456 		line = 9;
457 	}
458 
459 #if NIOAPIC > 0
460 	if (mp_busses != NULL) {
461 		if (mp_isa_bus != NULL &&
462 		    intr_find_mpmapping(mp_isa_bus->mb_idx, line, &ihp->line) == 0) {
463 			ihp->line |= line;
464 			return 0;
465 		}
466 #if NEISA > 0
467 		if (mp_eisa_bus != NULL &&
468 		    intr_find_mpmapping(mp_eisa_bus->mb_idx, line, &ihp->line) == 0) {
469 			ihp->line |= line;
470 			return 0;
471 		}
472 #endif
473 		printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n",
474 		    bus, dev, func, pin, line);
475 		printf("pci_intr_map: no MP mapping found\n");
476 	}
477 #endif
478 
479 	return 0;
480 
481 bad:
482 	ihp->line = -1;
483 	return 1;
484 }
485 
486 const char *
487 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
488 {
489 	static char irqstr[64];
490 
491 	if (ih.line == 0)
492 		panic("pci_intr_string: bogus handle 0x%x", ih.line);
493 
494 #if NIOAPIC > 0
495 	if (ih.line & APIC_INT_VIA_APIC)
496 		snprintf(irqstr, sizeof(irqstr), "apic %d int %d (irq %d)",
497 		    APIC_IRQ_APIC(ih.line),
498 		    APIC_IRQ_PIN(ih.line),
499 		    pci_intr_line(ih));
500 	else
501 		snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(ih));
502 #else
503 	snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(ih));
504 #endif
505 	return (irqstr);
506 }
507 
508 #include "acpiprt.h"
509 #if NACPIPRT > 0
510 void	acpiprt_route_interrupt(int bus, int dev, int pin);
511 #endif
512 
513 void *
514 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
515     int (*func)(void *), void *arg, char *what)
516 {
517 	int pin, irq;
518 	int bus, dev;
519 	struct pic *pic;
520 
521 	pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
522 #if NACPIPRT > 0
523 	acpiprt_route_interrupt(bus, dev, ih.pin);
524 #endif
525 
526 	pic = &i8259_pic;
527 	pin = irq = ih.line;
528 
529 #if NIOAPIC > 0
530 	if (ih.line & APIC_INT_VIA_APIC) {
531 		pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
532 		if (pic == NULL) {
533 			printf("pci_intr_establish: bad ioapic %d\n",
534 			    APIC_IRQ_APIC(ih.line));
535 			return NULL;
536 		}
537 		pin = APIC_IRQ_PIN(ih.line);
538 		irq = APIC_IRQ_LEGACY_IRQ(ih.line);
539 		if (irq < 0 || irq >= NUM_LEGACY_IRQS)
540 			irq = -1;
541 	}
542 #endif
543 
544 	return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
545 }
546 
547 void
548 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
549 {
550 	intr_disestablish(cookie);
551 }
552