Changeset View
Changeset View
Standalone View
Standalone View
sys/x86/x86/local_apic.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | |||||
#ifdef DDB | #ifdef DDB | ||||
#include <sys/interrupt.h> | #include <sys/interrupt.h> | ||||
#include <ddb/ddb.h> | #include <ddb/ddb.h> | ||||
#endif | #endif | ||||
#ifdef __amd64__ | #ifdef __amd64__ | ||||
#define SDT_APIC SDT_SYSIGT | #define SDT_APIC SDT_SYSIGT | ||||
#define SDT_APICT SDT_SYSIGT | |||||
#define GSEL_APIC 0 | #define GSEL_APIC 0 | ||||
#else | #else | ||||
#define SDT_APIC SDT_SYS386IGT | #define SDT_APIC SDT_SYS386IGT | ||||
#define SDT_APICT SDT_SYS386TGT | |||||
#define GSEL_APIC GSEL(GCODE_SEL, SEL_KPL) | #define GSEL_APIC GSEL(GCODE_SEL, SEL_KPL) | ||||
#endif | #endif | ||||
static MALLOC_DEFINE(M_LAPIC, "local_apic", "Local APIC items"); | static MALLOC_DEFINE(M_LAPIC, "local_apic", "Local APIC items"); | ||||
/* Sanity checks on IDT vectors. */ | /* Sanity checks on IDT vectors. */ | ||||
CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT); | CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT); | ||||
CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS); | CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS); | ||||
▲ Show 20 Lines • Show All 418 Lines • ▼ Show 20 Lines | #endif | ||||
/* Local APIC error interrupt. */ | /* Local APIC error interrupt. */ | ||||
setidt(APIC_ERROR_INT, pti ? IDTVEC(errorint_pti) : IDTVEC(errorint), | setidt(APIC_ERROR_INT, pti ? IDTVEC(errorint_pti) : IDTVEC(errorint), | ||||
SDT_APIC, SEL_KPL, GSEL_APIC); | SDT_APIC, SEL_KPL, GSEL_APIC); | ||||
/* XXX: Thermal interrupt */ | /* XXX: Thermal interrupt */ | ||||
/* Local APIC CMCI. */ | /* Local APIC CMCI. */ | ||||
setidt(APIC_CMC_INT, pti ? IDTVEC(cmcint_pti) : IDTVEC(cmcint), | setidt(APIC_CMC_INT, pti ? IDTVEC(cmcint_pti) : IDTVEC(cmcint), | ||||
SDT_APICT, SEL_KPL, GSEL_APIC); | SDT_APIC, SEL_KPL, GSEL_APIC); | ||||
if ((resource_int_value("apic", 0, "clock", &i) != 0 || i != 0)) { | if ((resource_int_value("apic", 0, "clock", &i) != 0 || i != 0)) { | ||||
arat = 0; | arat = 0; | ||||
/* Intel CPUID 0x06 EAX[2] set if APIC timer runs in C3. */ | /* Intel CPUID 0x06 EAX[2] set if APIC timer runs in C3. */ | ||||
if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high >= 6) { | if (cpu_vendor_id == CPU_VENDOR_INTEL && cpu_high >= 6) { | ||||
do_cpuid(0x06, regs); | do_cpuid(0x06, regs); | ||||
if ((regs[0] & CPUTPM1_ARAT) != 0) | if ((regs[0] & CPUTPM1_ARAT) != 0) | ||||
arat = 1; | arat = 1; | ||||
▲ Show 20 Lines • Show All 1,071 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
KASSERT(ioint_handlers[vector / 32] != NULL, | KASSERT(ioint_handlers[vector / 32] != NULL, | ||||
("No ISR handler for vector %u", vector)); | ("No ISR handler for vector %u", vector)); | ||||
#ifdef notyet | #ifdef notyet | ||||
/* | /* | ||||
* We can not currently clear the idt entry because other cpus | * We can not currently clear the idt entry because other cpus | ||||
* may have a valid vector at this offset. | * may have a valid vector at this offset. | ||||
*/ | */ | ||||
setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APICT, | setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APIC, | ||||
SEL_KPL, GSEL_APIC); | SEL_KPL, GSEL_APIC); | ||||
#endif | #endif | ||||
} | } | ||||
/* Release an APIC vector when it's no longer in use. */ | /* Release an APIC vector when it's no longer in use. */ | ||||
static void | static void | ||||
native_apic_free_vector(u_int apic_id, u_int vector, u_int irq) | native_apic_free_vector(u_int apic_id, u_int vector, u_int irq) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 524 Lines • ▼ Show 20 Lines | KASSERT(vector >= IPI_DYN_FIRST && vector <= IPI_DYN_LAST, | ||||
("%s: invalid vector %d", __func__, vector)); | ("%s: invalid vector %d", __func__, vector)); | ||||
mtx_lock_spin(&icu_lock); | mtx_lock_spin(&icu_lock); | ||||
ip = &idt[vector]; | ip = &idt[vector]; | ||||
func = (ip->gd_hioffset << 16) | ip->gd_looffset; | func = (ip->gd_hioffset << 16) | ip->gd_looffset; | ||||
KASSERT(func != (uintptr_t)&IDTVEC(rsvd) && | KASSERT(func != (uintptr_t)&IDTVEC(rsvd) && | ||||
func != (uintptr_t)&IDTVEC(rsvd_pti), | func != (uintptr_t)&IDTVEC(rsvd_pti), | ||||
("invalid idtfunc %#lx", func)); | ("invalid idtfunc %#lx", func)); | ||||
setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APICT, | setidt(vector, pti ? &IDTVEC(rsvd_pti) : &IDTVEC(rsvd), SDT_APIC, | ||||
SEL_KPL, GSEL_APIC); | SEL_KPL, GSEL_APIC); | ||||
mtx_unlock_spin(&icu_lock); | mtx_unlock_spin(&icu_lock); | ||||
} | } |