Line data Source code
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 0 : aapic_match(struct device *parent, void *match, void *aux)
44 : {
45 0 : struct pci_attach_args *pa = aux;
46 :
47 0 : if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD &&
48 0 : PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_8131_PCIX_IOAPIC)
49 0 : return (1);
50 :
51 0 : return (0);
52 0 : }
53 :
54 : void
55 0 : aapic_attach(struct device *parent, struct device *self, void *aux)
56 : {
57 0 : struct pci_attach_args *pa = aux;
58 0 : int bus, dev, func;
59 : pcitag_t tag;
60 : pcireg_t reg;
61 :
62 0 : printf("\n");
63 :
64 : #if NIOAPIC > 0
65 0 : if (nioapics == 0)
66 0 : return;
67 : #else
68 : return;
69 : #endif
70 :
71 0 : reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL);
72 0 : reg |= AMD8131_IOAEN;
73 0 : pci_conf_write(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL, reg);
74 :
75 0 : pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
76 0 : func = 0;
77 0 : tag = pci_make_tag(pa->pa_pc, bus, dev, func);
78 0 : reg = pci_conf_read(pa->pa_pc, tag, AMD8131_PCIX_MISC);
79 0 : reg &= ~AMD8131_NIOAMODE;
80 0 : pci_conf_write(pa->pa_pc, tag, AMD8131_PCIX_MISC, reg);
81 0 : }
|