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