summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2007-01-28 18:24:22 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2007-01-28 18:24:22 +0000
commit77fef2b26702f8178525db3d4a3fa7b5bd3725c3 (patch)
treed9929c1103b93bec3d527735ab38ceb94f0bf195 /sys
parente6ff74b9d1af654a02b7cc8fa95f59fd34245a58 (diff)
Properly route lapic NMIs.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpimadt.c39
1 files changed, 38 insertions, 1 deletions
diff --git a/sys/dev/acpi/acpimadt.c b/sys/dev/acpi/acpimadt.c
index b8bb052b176..0003469efd5 100644
--- a/sys/dev/acpi/acpimadt.c
+++ b/sys/dev/acpi/acpimadt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpimadt.c,v 1.6 2007/01/11 22:01:05 kettenis Exp $ */
+/* $OpenBSD: acpimadt.c,v 1.7 2007/01/28 18:24:21 kettenis Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis <kettenis@openbsd.org>
*
@@ -36,6 +36,10 @@
#include "ioapic.h"
+#ifdef __amd64__ /* XXX */
+#define mp_nintrs mp_nintr
+#endif
+
int acpimadt_match(struct device *, void *, void *);
void acpimadt_attach(struct device *, struct device *, void *);
@@ -109,6 +113,8 @@ acpimadt_cfg_intr(int flags, u_int32_t *redir)
}
}
+static u_int8_t lapic_map[256];
+
void
acpimadt_attach(struct device *parent, struct device *self, void *aux)
{
@@ -119,6 +125,7 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
struct mp_intr_map *map;
struct ioapic_softc *apic;
int cpu_role = CPU_ROLE_BP;
+ int nlapic_nmis = 0;
int pin;
printf(" addr 0x%x", madt->local_apic_address);
@@ -141,6 +148,10 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
entry->madt_lapic.acpi_proc_id,
entry->madt_lapic.apic_id,
entry->madt_lapic.flags);
+
+ lapic_map[entry->madt_lapic.acpi_proc_id] =
+ entry->madt_lapic.apic_id;
+
{
struct cpu_attach_args caa;
@@ -181,10 +192,17 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
config_found(mainbus, &aaa, acpimadt_print);
}
break;
+ case ACPI_MADT_LAPIC_NMI:
+ nlapic_nmis++;
+ break;
}
addr += entry->madt_lapic.length;
}
+ mp_intrs = malloc(nlapic_nmis * sizeof (struct mp_intr_map), M_DEVBUF, M_NOWAIT);
+ if (mp_intrs == NULL)
+ return;
+
/* 2nd pass, get interrupt overrides */
addr = (caddr_t)(madt + 1);
while (addr < (caddr_t)madt + madt->hdr.length) {
@@ -229,6 +247,25 @@ acpimadt_attach(struct device *parent, struct device *self, void *aux)
mp_isa_bus->mb_intrs = map;
break;
+ case ACPI_MADT_LAPIC_NMI:
+ printf("LAPIC_NMI: acpi_proc_id %x, local_apic_lint %x, flags %x\n",
+ entry->madt_lapic_nmi.acpi_proc_id,
+ entry->madt_lapic_nmi.local_apic_lint,
+ entry->madt_lapic_nmi.flags);
+
+ pin = entry->madt_lapic_nmi.local_apic_lint;
+
+ map = &mp_intrs[mp_nintrs++];
+ memset(map, 0, sizeof *map);
+ map->cpu_id = lapic_map[entry->madt_lapic_nmi.acpi_proc_id];
+ map->ioapic_pin = pin;
+ map->flags = entry->madt_lapic_nmi.flags;
+
+ acpimadt_cfg_intr(entry->madt_override.flags, &map->redir);
+ map->redir &= ~IOAPIC_REDLO_DEL_MASK;
+ map->redir |= (IOAPIC_REDLO_DEL_NMI << IOAPIC_REDLO_DEL_SHIFT);
+ break;
+
default:
printf("apic_type %x\n", entry->madt_lapic.apic_type);
}