diff --git a/kernel-src/arch/x86-64/apic.c b/kernel-src/arch/x86-64/apic.c index 741cd950..ad981aee 100644 --- a/kernel-src/arch/x86-64/apic.c +++ b/kernel-src/arch/x86-64/apic.c @@ -18,6 +18,7 @@ #define APIC_REG_EOI 0xB0 #define APIC_REG_SPURIOUS 0xF0 #define APIC_REG_ICR_LO 0x300 +#define APIC_REG_ICR_LO_STATUS (1 << 12) #define APIC_REG_ICR_HI 0x310 #define APIC_LVT_TIMER 0x320 #define APIC_LVT_THERMAL 0x330 @@ -279,6 +280,13 @@ void arch_apic_timerinit() { __assert(_cpu()->timer); } +void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level) { + while (readlapic(APIC_REG_ICR_LO) & APIC_REG_ICR_LO_STATUS) CPU_PAUSE(); + + writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24); + writelapic(APIC_REG_ICR_LO, vec | (level << 14) | (mode << 15) | (dest << 18)); +} + void arch_apic_init() { madt = arch_acpi_findtable("APIC", 0); __assert(madt); diff --git a/kernel-src/include/x86-64/arch/apic.h b/kernel-src/include/x86-64/arch/apic.h index 03892667..f1318b09 100644 --- a/kernel-src/include/x86-64/arch/apic.h +++ b/kernel-src/include/x86-64/arch/apic.h @@ -6,5 +6,6 @@ void arch_apic_init(); void arch_apic_initap(); void arch_apic_eoi(); void arch_ioapic_setirq(uint8_t gsi, uint8_t vector, uint8_t proc, bool masked); +void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uint8_t level); #endif