mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +00:00
Rework the APIC mixed mode support a bit:
- Require the APIC enumerators to explicitly enable mixed mode by calling ioapic_enable_mixed_mode(). Calling this function tells the apic driver that the PC-AT 8259A PICs are present and routable through the first I/O APIC via an ExtINT pin. The mptable enumerator always calls this function for now. The MADT enumerator only enables mixed mode if the PC-AT compatability flag is set in the MADT header. - Allow mixed mode to be enabled or disabled via a 'hw.apic.mixed_mode' tunable. By default this tunable is set to 1 (true). The kernel option NO_MIXED_MODE changes the default to 0 to preserve existing behavior, but adding 'hw.apic.mixed_mode=0' to loader.conf achieves the same effect. - Only use mixed mode to route IRQ 0 if it is both enabled by the APIC enumerator and activated by the loader tunable. Note that both conditions must be true, so if the APIC enumerator does not enable mixed mode, then you can't set the tunable to try to override the enumerator.
This commit is contained in:
parent
02ebd2bcb5
commit
eb8943b13e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129097
@ -368,6 +368,8 @@ madt_setup_io(void)
|
||||
}
|
||||
|
||||
/* First, we run through adding I/O APIC's. */
|
||||
if (madt->PCATCompat)
|
||||
ioapic_enable_mixed_mode();
|
||||
madt_walk_table(madt_parse_apics, NULL);
|
||||
|
||||
/* Second, we run through the table tweaking interrupt sources. */
|
||||
|
@ -50,10 +50,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/apicvar.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
#if defined(DEV_ISA) && !defined(NO_MIXED_MODE)
|
||||
#define MIXED_MODE
|
||||
#endif
|
||||
|
||||
#define IOAPIC_ISA_INTS 16
|
||||
#define IOAPIC_MEM_REGION 32
|
||||
#define IOAPIC_REDTBL_LO(i) (IOAPIC_REDTBL + (i) * 2)
|
||||
@ -116,8 +112,6 @@ struct ioapic {
|
||||
struct ioapic_intsrc io_pins[0];
|
||||
};
|
||||
|
||||
static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list);
|
||||
static u_int next_id, program_logical_dest;
|
||||
|
||||
static u_int ioapic_read(volatile ioapic_t *apic, int reg);
|
||||
static void ioapic_write(volatile ioapic_t *apic, int reg, u_int val);
|
||||
@ -132,17 +126,23 @@ static int ioapic_config_intr(struct intsrc *isrc, enum intr_trigger trig,
|
||||
static void ioapic_suspend(struct intsrc *isrc);
|
||||
static void ioapic_resume(struct intsrc *isrc);
|
||||
static void ioapic_program_destination(struct ioapic_intsrc *intpin);
|
||||
#ifdef MIXED_MODE
|
||||
static void ioapic_setup_mixed_mode(struct ioapic_intsrc *intpin);
|
||||
#endif
|
||||
|
||||
static STAILQ_HEAD(,ioapic) ioapic_list = STAILQ_HEAD_INITIALIZER(ioapic_list);
|
||||
struct pic ioapic_template = { ioapic_enable_source, ioapic_disable_source,
|
||||
ioapic_eoi_source, ioapic_enable_intr,
|
||||
ioapic_vector, ioapic_source_pending,
|
||||
ioapic_suspend, ioapic_resume,
|
||||
ioapic_config_intr };
|
||||
|
||||
static int next_ioapic_base, logical_clusters, current_cluster;
|
||||
static int current_cluster, logical_clusters, next_ioapic_base;
|
||||
static u_int mixed_mode_enabled, next_id, program_logical_dest;
|
||||
#ifdef NO_MIXED_MODE
|
||||
static int mixed_mode_active = 0;
|
||||
#else
|
||||
static int mixed_mode_active = 1;
|
||||
#endif
|
||||
TUNABLE_INT("hw.apic.mixed_mode", &mixed_mode_active);
|
||||
|
||||
static u_int
|
||||
ioapic_read(volatile ioapic_t *apic, int reg)
|
||||
@ -342,6 +342,17 @@ ioapic_resume(struct intsrc *isrc)
|
||||
TODO;
|
||||
}
|
||||
|
||||
/*
|
||||
* APIC enumerators call this function to indicate that the 8259A AT PICs
|
||||
* are available and that mixed mode can be used.
|
||||
*/
|
||||
void
|
||||
ioapic_enable_mixed_mode(void)
|
||||
{
|
||||
|
||||
mixed_mode_enabled = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate and return a logical cluster ID. Note that the first time
|
||||
* this is called, it returns cluster 0. ioapic_enable_intr() treats
|
||||
@ -417,14 +428,17 @@ ioapic_create(uintptr_t addr, int32_t apic_id, int intbase)
|
||||
* Assume that pin 0 on the first IO APIC is an ExtINT pin by
|
||||
* default. Assume that intpins 1-15 are ISA interrupts and
|
||||
* use suitable defaults for those. Assume that all other
|
||||
* intpins are PCI interrupts. Enable the ExtINT pin by
|
||||
* default but mask all other pins.
|
||||
* intpins are PCI interrupts. Enable the ExtINT pin if
|
||||
* mixed mode is available and active but mask all other pins.
|
||||
*/
|
||||
if (intpin->io_vector == 0) {
|
||||
intpin->io_activehi = 1;
|
||||
intpin->io_edgetrigger = 1;
|
||||
intpin->io_vector = VECTOR_EXTINT;
|
||||
if (mixed_mode_enabled && mixed_mode_active)
|
||||
intpin->io_masked = 0;
|
||||
else
|
||||
intpin->io_masked = 1;
|
||||
} else if (intpin->io_vector < IOAPIC_ISA_INTS) {
|
||||
intpin->io_activehi = 1;
|
||||
intpin->io_edgetrigger = 1;
|
||||
@ -669,12 +683,15 @@ ioapic_register(void *cookie)
|
||||
ioapic_write(apic, IOAPIC_REDTBL_HI(i), flags);
|
||||
mtx_unlock_spin(&icu_lock);
|
||||
if (pin->io_vector < NUM_IO_INTS) {
|
||||
#ifdef MIXED_MODE
|
||||
/* Route IRQ0 via the 8259A using mixed mode. */
|
||||
if (pin->io_vector == 0)
|
||||
|
||||
/*
|
||||
* Route IRQ0 via the 8259A using mixed mode if
|
||||
* mixed mode is available and turned on.
|
||||
*/
|
||||
if (pin->io_vector == 0 && mixed_mode_active &&
|
||||
mixed_mode_enabled)
|
||||
ioapic_setup_mixed_mode(pin);
|
||||
else
|
||||
#endif
|
||||
intr_register_source(&pin->io_intsrc);
|
||||
}
|
||||
|
||||
@ -701,7 +718,6 @@ ioapic_set_logical_destinations(void *arg __unused)
|
||||
SYSINIT(ioapic_destinations, SI_SUB_SMP, SI_ORDER_SECOND,
|
||||
ioapic_set_logical_destinations, NULL)
|
||||
|
||||
#ifdef MIXED_MODE
|
||||
/*
|
||||
* Support for mixed-mode interrupt sources. These sources route an ISA
|
||||
* IRQ through the 8259A's via the ExtINT on pin 0 of the I/O APIC that
|
||||
@ -730,5 +746,3 @@ ioapic_setup_mixed_mode(struct ioapic_intsrc *intpin)
|
||||
ioapic_assign_cluster(extint);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* MIXED_MODE */
|
||||
|
@ -2778,6 +2778,11 @@ ioapic_disable_pin(void *cookie, u_int pin)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
void
|
||||
ioapic_enable_mixed_mode(void)
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
ioapic_get_vector(void *cookie, u_int pin)
|
||||
{
|
||||
|
@ -342,6 +342,7 @@ mptable_setup_io(void)
|
||||
busses[i].bus_type = NOBUS;
|
||||
|
||||
/* Second, we run through adding I/O APIC's and busses. */
|
||||
ioapic_enable_mixed_mode();
|
||||
mptable_parse_apics_and_busses();
|
||||
|
||||
/* Third, we run through the table tweaking interrupt sources. */
|
||||
|
@ -136,6 +136,7 @@ u_int apic_idt_to_irq(u_int vector);
|
||||
void apic_register_enumerator(struct apic_enumerator *enumerator);
|
||||
void *ioapic_create(uintptr_t addr, int32_t id, int intbase);
|
||||
int ioapic_disable_pin(void *cookie, u_int pin);
|
||||
void ioapic_enable_mixed_mode(void);
|
||||
int ioapic_get_vector(void *cookie, u_int pin);
|
||||
int ioapic_next_logical_cluster(void);
|
||||
void ioapic_register(void *cookie);
|
||||
|
Loading…
Reference in New Issue
Block a user