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:
parent
644e9151d0
commit
f493e906e6
|
@ -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) {
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue