1
0
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:
John Baldwin 2004-05-10 18:49:58 +00:00
parent 02ebd2bcb5
commit eb8943b13e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=129097
5 changed files with 42 additions and 19 deletions

View File

@ -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. */

View File

@ -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;
intpin->io_masked = 0;
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 */

View File

@ -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)
{

View File

@ -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. */

View File

@ -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);