From f6d9fb10b106843fb6e00d9a33a76285b6a4e1f9 Mon Sep 17 00:00:00 2001 From: "Charles E. Youse" Date: Tue, 24 Sep 2019 16:54:38 -0400 Subject: [PATCH] drivers/interrupt_controller/loapic.h: add IPI support Add a simple inline function and some definitions to faciliate inter-processor interrupts for SMP initialization/synchronization. Signed-off-by: Charles E. Youse --- include/drivers/interrupt_controller/loapic.h | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/include/drivers/interrupt_controller/loapic.h b/include/drivers/interrupt_controller/loapic.h index 6644cee9320..59093408b24 100644 --- a/include/drivers/interrupt_controller/loapic.h +++ b/include/drivers/interrupt_controller/loapic.h @@ -40,7 +40,12 @@ #define LOAPIC_TIMER_CCR 0x390 /* Timer Current Count Reg */ #define LOAPIC_TIMER_CONFIG 0x3e0 /* Timer Divide Config Reg */ -/* Local APIC Vector Table Bits */ +#define LOAPIC_ICR_BUSY 0x00001000 /* delivery status: 1 = busy */ + +#define LOAPIC_ICR_IPI_OTHERS 0x000C4000U /* normal IPI to other CPUs */ +#define LOAPIC_ICR_IPI_INIT 0x00004500U +#define LOAPIC_ICR_IPI_STARTUP 0x00004600U + #define LOAPIC_LVT_MASKED 0x00010000 /* mask */ #ifndef _ASMLANGUAGE @@ -137,6 +142,36 @@ static inline void x86_write_loapic(unsigned int reg, u32_t val) #endif } +/** + * @brief Send an IPI. + * + * @param apic_id If applicable, the target CPU APIC ID (0 otherwise). + * @param ipi Type of IPI: one of the LOAPIC_ICR_IPI_* constants. + * @param vector If applicable, the target vector (0 otherwise). + */ +static inline void z_loapic_ipi(u8_t apic_id, u32_t ipi, u8_t vector) +{ + ipi |= vector; + +#ifndef CONFIG_X2APIC + /* + * Legacy xAPIC mode: first wait for any previous IPI to be delivered. + */ + + while (x86_read_xapic(LOAPIC_ICRLO) & LOAPIC_ICR_BUSY) { + } + + x86_write_xapic(LOAPIC_ICRHI, apic_id << 24); + x86_write_xapic(LOAPIC_ICRLO, ipi); +#else + /* + * x2APIC mode is greatly simplified: one write, no delivery status. + */ + + x86_write_x2apic(LOAPIC_ICRLO, (((u64_t) apic_id) << 32) | ipi); +#endif +} + #ifdef __cplusplus } #endif