xref: /openbsd/sys/arch/amd64/pci/aapic.c (revision 09467b48)
1 /*	$OpenBSD: aapic.c,v 1.6 2015/03/14 03:38:46 jsg Exp $	*/
2 /* 	$NetBSD: aapic.c,v 1.3 2005/01/13 23:40:01 fvdl Exp $	*/
3 
4 /*
5  * The AMD 8131 IO APIC can hang the box when an APIC IRQ is masked.
6  */
7 #include <sys/param.h>
8 #include <sys/systm.h>
9 #include <sys/device.h>
10 
11 #include <dev/pci/pcireg.h>
12 #include <dev/pci/pcivar.h>
13 #include <dev/pci/pcidevs.h>
14 
15 #include "ioapic.h"
16 
17 #if NIOAPIC > 0
18 extern int nioapics;
19 #endif
20 
21 #define AMD8131_PCIX_MISC	0x40
22 #define AMD8131_NIOAMODE	0x00000001
23 
24 #define AMD8131_IOAPIC_CTL	0x44
25 #define AMD8131_IOAEN		0x00000002
26 
27 int	aapic_match(struct device *, void *, void *);
28 void	aapic_attach(struct device *, struct device *, void *);
29 
30 struct aapic_softc {
31 	struct device sc_dev;
32 };
33 
34 struct cfattach aapic_ca = {
35 	sizeof(struct aapic_softc), aapic_match, aapic_attach
36 };
37 
38 struct cfdriver aapic_cd = {
39 	0, "aapic", DV_DULL
40 };
41 
42 int
43 aapic_match(struct device *parent, void *match, void *aux)
44 {
45 	struct pci_attach_args *pa = aux;
46 
47 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
48 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_8131_PCIX_IOAPIC)
49 		return (1);
50 
51 	return (0);
52 }
53 
54 void
55 aapic_attach(struct device *parent, struct device *self, void *aux)
56 {
57 	struct pci_attach_args *pa = aux;
58 	int bus, dev, func;
59 	pcitag_t tag;
60 	pcireg_t reg;
61 
62 	printf("\n");
63 
64 #if NIOAPIC > 0
65 	if (nioapics == 0)
66 		return;
67 #else
68 	return;
69 #endif
70 
71 	reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL);
72 	reg |= AMD8131_IOAEN;
73 	pci_conf_write(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL, reg);
74 
75 	pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
76 	func = 0;
77 	tag = pci_make_tag(pa->pa_pc, bus, dev, func);
78 	reg = pci_conf_read(pa->pa_pc, tag, AMD8131_PCIX_MISC);
79 	reg &= ~AMD8131_NIOAMODE;
80 	pci_conf_write(pa->pa_pc, tag, AMD8131_PCIX_MISC, reg);
81 }
82