1 /* $NetBSD: aapic.c,v 1.4 2005/12/11 12:19:47 christos Exp $ */ 2 3 #include <sys/cdefs.h> 4 __KERNEL_RCSID(0, "$NetBSD: aapic.c,v 1.4 2005/12/11 12:19:47 christos Exp $"); 5 6 #include <sys/param.h> 7 #include <sys/systm.h> 8 #include <sys/kernel.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 <arch/x86/pci/amd8131reg.h> 16 17 #include "ioapic.h" 18 19 #if NIOAPIC > 0 20 extern int nioapics; 21 #endif 22 23 static int aapic_match __P((struct device *, struct cfdata *, void *)); 24 static void aapic_attach __P((struct device *, struct device *, void *)); 25 26 struct aapic_softc { 27 struct device sc_dev; 28 }; 29 30 CFATTACH_DECL(aapic, sizeof(struct aapic_softc), 31 aapic_match, aapic_attach, NULL, NULL); 32 33 static int 34 aapic_match(parent, match, aux) 35 struct device *parent; 36 struct cfdata *match; 37 void *aux; 38 { 39 struct pci_attach_args *pa = aux; 40 41 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_AMD && 42 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_AMD_PCIX8131_APIC) 43 return (1); 44 45 return (0); 46 } 47 48 static void 49 aapic_attach(parent, self, aux) 50 struct device *parent, *self; 51 void *aux; 52 { 53 struct pci_attach_args *pa = aux; 54 char devinfo[256]; 55 int bus, dev, func, rev; 56 pcitag_t tag; 57 pcireg_t reg; 58 59 pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo)); 60 rev = PCI_REVISION(pa->pa_class); 61 printf(": %s (rev. 0x%02x)\n", devinfo, rev); 62 63 #if NIOAPIC > 0 64 if (nioapics == 0) 65 return; 66 #else 67 return; 68 #endif 69 70 reg = pci_conf_read(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL); 71 reg |= AMD8131_IOAEN; 72 pci_conf_write(pa->pa_pc, pa->pa_tag, AMD8131_IOAPIC_CTL, reg); 73 74 pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func); 75 func = 0; 76 tag = pci_make_tag(pa->pa_pc, bus, dev, func); 77 reg = pci_conf_read(pa->pa_pc, tag, AMD8131_PCIX_MISC); 78 reg &= ~AMD8131_NIOAMODE; 79 pci_conf_write(pa->pa_pc, tag, AMD8131_PCIX_MISC, reg); 80 } 81