Handle per-CPU local apic redir entries a little better. My previous

solution relied on CPU entries coming first in the table, which
isn't guaranteed. Instead, export mp_intrs to lapic.c, and scan
it for entries that match the current CPU in lapic_set_lvt().

Also, do not try to up intr_cnt by the number of IO APICs or CPUs in
the case of MPS_ALL_APICS; it isn't needed, and it also relies on
CPU and IO APIC entries being earlier in the table.
This commit is contained in:
fvdl 2002-10-06 20:38:37 +00:00
parent 644e9151d0
commit f493e906e6
2 changed files with 26 additions and 26 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: lapic.c,v 1.3 2002/10/06 14:28:55 fvdl Exp $ */ /* $NetBSD: lapic.c,v 1.4 2002/10/06 20:38:38 fvdl Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -58,6 +58,7 @@
#include <machine/cpuvar.h> #include <machine/cpuvar.h>
#include <machine/pmap.h> #include <machine/pmap.h>
#include <machine/vmparam.h> #include <machine/vmparam.h>
#include <machine/mpbiosreg.h>
#include <machine/mpbiosvar.h> #include <machine/mpbiosvar.h>
#include <machine/pcb.h> #include <machine/pcb.h>
#include <machine/specialreg.h> #include <machine/specialreg.h>
@ -114,12 +115,12 @@ lapic_enable()
i82489_writereg(LAPIC_SVR, LAPIC_SVR_ENABLE | LAPIC_SPURIOUS_VECTOR); i82489_writereg(LAPIC_SVR, LAPIC_SVR_ENABLE | LAPIC_SPURIOUS_VECTOR);
} }
extern struct mp_intr_map *lapic_ints[]; /* XXX header file? */
void void
lapic_set_lvt () lapic_set_lvt ()
{ {
struct cpu_info *ci = curcpu(); struct cpu_info *ci = curcpu();
int i;
struct mp_intr_map *mpi;
#ifdef MULTIPROCESSOR #ifdef MULTIPROCESSOR
if (mp_verbose) { if (mp_verbose) {
@ -129,10 +130,21 @@ lapic_set_lvt ()
i82489_readreg(LAPIC_LVINT1)); i82489_readreg(LAPIC_LVINT1));
} }
#endif #endif
if (ci->ci_lapic_ints[0]) for (i = 0; i < mp_nintr; i++) {
i82489_writereg(LAPIC_LVINT0, ci->ci_lapic_ints[0]->redir); mpi = &mp_intrs[i];
if (ci->ci_lapic_ints[1]) if (mpi->ioapic == NULL && (mpi->cpu_id == MPS_ALL_APICS
i82489_writereg(LAPIC_LVINT1, ci->ci_lapic_ints[1]->redir); || mpi->cpu_id == ci->ci_cpuid)) {
#ifdef DIAGNOSTIC
if (mpi->ioapic_pin > 1)
panic("lapic_set_lvt: bad pin value %d",
mpi->ioapic_pin);
#endif
if (mpi->ioapic_pin == 0)
i82489_writereg(LAPIC_LVINT0, mpi->redir);
else
i82489_writereg(LAPIC_LVINT1, mpi->redir);
}
}
#ifdef MULTIPROCESSOR #ifdef MULTIPROCESSOR
if (mp_verbose) { if (mp_verbose) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: mpbios.c,v 1.4 2002/10/06 14:28:55 fvdl Exp $ */ /* $NetBSD: mpbios.c,v 1.5 2002/10/06 20:38:37 fvdl Exp $ */
/*- /*-
* Copyright (c) 2000 The NetBSD Foundation, Inc. * Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -454,6 +454,7 @@ static struct mpbios_baseentry mp_conf[] =
struct mp_bus *mp_busses; struct mp_bus *mp_busses;
int mp_nbus; int mp_nbus;
struct mp_intr_map *mp_intrs; struct mp_intr_map *mp_intrs;
int mp_nintr;
int mp_isa_bus = -1; /* XXX */ int mp_isa_bus = -1; /* XXX */
int mp_eisa_bus = -1; /* XXX */ int mp_eisa_bus = -1; /* XXX */
@ -599,16 +600,8 @@ mpbios_scan(self)
* apics of this type". * apics of this type".
*/ */
if ((type == MPS_MCT_IOINT) || if ((type == MPS_MCT_IOINT) ||
(type == MPS_MCT_LINT)) { (type == MPS_MCT_LINT))
const struct mpbios_int *ie =
(const struct mpbios_int *)position;
if (ie->dst_apic_id != MPS_ALL_APICS)
intr_cnt++; intr_cnt++;
else if (type == MPS_MCT_IOINT)
intr_cnt += mp_conf[MPS_MCT_IOAPIC].count;
else
intr_cnt += mp_conf[MPS_MCT_CPU].count;
}
position += mp_conf[type].length; position += mp_conf[type].length;
} }
@ -617,6 +610,7 @@ mpbios_scan(self)
memset(mp_busses, 0, sizeof(struct mp_bus) * mp_nbus); memset(mp_busses, 0, sizeof(struct mp_bus) * mp_nbus);
mp_intrs = malloc(sizeof(struct mp_intr_map)*intr_cnt, mp_intrs = malloc(sizeof(struct mp_intr_map)*intr_cnt,
M_DEVBUF, M_NOWAIT); M_DEVBUF, M_NOWAIT);
mp_nintr = intr_cnt;
/* re-walk the table, recording info of interest */ /* re-walk the table, recording info of interest */
position = (const u_int8_t *) mp_cth + sizeof(*mp_cth); position = (const u_int8_t *) mp_cth + sizeof(*mp_cth);
@ -999,9 +993,6 @@ mpbios_int(ent, enttype, mpi)
u_int32_t type = entry->int_type; u_int32_t type = entry->int_type;
u_int32_t flags = entry->int_flags; u_int32_t flags = entry->int_flags;
struct cpu_info *ci;
CPU_INFO_ITERATOR cii;
switch (type) { switch (type) {
case MPS_INTTYPE_INT: case MPS_INTTYPE_INT:
mpb = &(mp_busses[bus]); mpb = &(mp_busses[bus]);
@ -1062,10 +1053,7 @@ mpbios_int(ent, enttype, mpi)
else { else {
mpi->ioapic = NULL; mpi->ioapic = NULL;
mpi->ioapic_pin = pin; mpi->ioapic_pin = pin;
for (CPU_INFO_FOREACH(cii, ci)) { mpi->cpu_id = id;
if (id == MPS_ALL_APICS || ci->ci_cpuid == id)
ci->ci_lapic_ints[pin] = mpi;
}
} }
} }
if (mp_verbose) { if (mp_verbose) {