Merge intr.c (1.29.8.2) and ioapic.c (1.19.8.5) changes from jmcneill-pm:

Always write entries to all IOAPIC pins. The first 16 pins are
threated as ISA IRQs by default, the others like PCI IRQs. This avoids
inconsistencies based on incomplete BIOS setups. This resulted in early
ACPI SCI notifications to be lost, effectively breaking the Embedded
Controller on cold start on many notebooks.

Don't special case the IOAPIC setup between ioapic_attach and
ioapic_enable, always setup the correct redirections. Depend on
splhigh/disable_intr to stop interrupts and don't keep them masked in
the IOAPIC. This avoids unacknowleged edge interrupts and fixing the problem
of broken PS/2 keyboard when hitting keys during early boot.
This commit is contained in:
joerg 2007-10-07 14:23:42 +00:00
parent ab21cdda12
commit 0c403c87a2
2 changed files with 22 additions and 43 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.32 2007/08/30 11:32:09 ad Exp $ */
/* $NetBSD: intr.c,v 1.33 2007/10/07 14:23:42 joerg Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@ -140,7 +140,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.32 2007/08/30 11:32:09 ad Exp $");
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.33 2007/10/07 14:23:42 joerg Exp $");
#include "opt_multiprocessor.h"
#include "opt_acpi.h"
@ -684,8 +684,7 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
source->is_type, pic->pic_dev.dv_xname, pin);
}
if (!cold)
pic->pic_hwmask(pic, pin);
pic->pic_hwmask(pic, pin);
/*
* Figure out where to put the handler.
@ -731,8 +730,7 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
pic->pic_addroute(pic, ci, pin, idt_vec, type);
if (!cold)
pic->pic_hwunmask(pic, pin);
pic->pic_hwunmask(pic, pin);
#ifdef INTRDEBUG
printf("allocated pic %s type %s pin %d level %d to cpu%u slot %d idt entry %d\n",

View File

@ -1,4 +1,4 @@
/* $NetBSD: ioapic.c,v 1.21 2007/10/06 04:37:06 joerg Exp $ */
/* $NetBSD: ioapic.c,v 1.22 2007/10/07 14:23:42 joerg Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ioapic.c,v 1.21 2007/10/06 04:37:06 joerg Exp $");
__KERNEL_RCSID(0, "$NetBSD: ioapic.c,v 1.22 2007/10/07 14:23:42 joerg Exp $");
#include "opt_ddb.h"
@ -119,7 +119,6 @@ static void ioapic_delroute(struct pic *, struct cpu_info *, int, int, int);
int apic_verbose = 0;
int ioapic_bsp_id = 0;
int ioapic_cold = 1;
struct ioapic_softc *ioapics; /* head of linked list */
int nioapics = 0; /* number attached */
@ -342,10 +341,25 @@ ioapic_attach(struct device *parent, struct device *self, void *aux)
M_DEVBUF, M_WAITOK);
for (i=0; i<sc->sc_apic_sz; i++) {
uint32_t redlo;
sc->sc_pins[i].ip_next = NULL;
sc->sc_pins[i].ip_map = NULL;
sc->sc_pins[i].ip_vector = 0;
sc->sc_pins[i].ip_type = IST_NONE;
/* Mask all pins by default. */
redlo = IOAPIC_REDLO_MASK;
/*
* ISA interrupts are connect to pin 0-15 and
* edge triggered on high, which is the default.
*
* Expect all other interrupts to be PCI-like
* level triggered on low.
*/
if (i >= 16)
redlo = IOAPIC_REDLO_LEVEL | IOAPIC_REDLO_ACTLO;
ioapic_write(sc, IOAPIC_REDLO(i), redlo);
}
/*
@ -444,12 +458,6 @@ apic_set_redir(struct ioapic_softc *sc, int pin, int idt_vec,
void
ioapic_enable(void)
{
int p;
struct ioapic_softc *sc;
struct ioapic_pin *ip;
ioapic_cold = 0;
if (ioapics == NULL)
return;
@ -459,17 +467,6 @@ ioapic_enable(void)
outb(IMCR_ADDR, IMCR_REGISTER);
outb(IMCR_DATA, IMCR_APIC);
}
for (sc = ioapics; sc != NULL; sc = sc->sc_next) {
aprint_debug("%s: enabling\n", sc->sc_pic.pic_dev.dv_xname);
for (p = 0; p < sc->sc_apic_sz; p++) {
ip = &sc->sc_pins[p];
if (ip->ip_type != IST_NONE)
apic_set_redir(sc, p, ip->ip_vector,
ip->ip_cpu);
}
}
}
void
@ -479,8 +476,6 @@ ioapic_hwmask(struct pic *pic, int pin)
struct ioapic_softc *sc = (struct ioapic_softc *)pic;
u_long flags;
if (ioapic_cold)
return;
flags = ioapic_lock(sc);
redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
redlo |= IOAPIC_REDLO_MASK;
@ -495,9 +490,6 @@ ioapic_hwunmask(struct pic *pic, int pin)
struct ioapic_softc *sc = (struct ioapic_softc *)pic;
u_long flags;
if (ioapic_cold) {
return;
}
flags = ioapic_lock(sc);
redlo = ioapic_read_ul(sc, IOAPIC_REDLO(pin));
redlo &= ~IOAPIC_REDLO_MASK;
@ -517,9 +509,6 @@ ioapic_addroute(struct pic *pic, struct cpu_info *ci, int pin,
pp->ip_type = type;
pp->ip_vector = idtvec;
pp->ip_cpu = ci;
if (ioapic_cold) {
return;
}
apic_set_redir(sc, pin, idtvec, ci);
}
@ -527,14 +516,6 @@ static void
ioapic_delroute(struct pic *pic, struct cpu_info *ci, int pin,
int idtvec, int type)
{
struct ioapic_softc *sc = (struct ioapic_softc *)pic;
struct ioapic_pin *pp;
if (ioapic_cold) {
pp = &sc->sc_pins[pin];
pp->ip_type = IST_NONE;
return;
}
ioapic_hwmask(pic, pin);
}