From 2b1bccde07773c64a59c95df26d4b51113491d33 Mon Sep 17 00:00:00 2001 From: Enjia Mai Date: Mon, 28 Feb 2022 11:05:33 +0800 Subject: [PATCH] tests: testsuite: add emulating send IPI in X2APIC mode We emulate the interrupt by sending the IPI to core itself by the local APIC for x86 platfrom. But in X2APIC mode, this no longer works. So we emulate the interrupt the by writing the IA32_X2APIC_SELF_IPI MSR to send IPI to the core itself via LOAPIC also. According to SDM vol.3 chapter 10.12.11. Fixes #42108 Signed-off-by: Enjia Mai --- include/drivers/interrupt_controller/loapic.h | 1 + subsys/testsuite/include/interrupt_util.h | 25 ++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/include/drivers/interrupt_controller/loapic.h b/include/drivers/interrupt_controller/loapic.h index 698ffc30b58..23671fa011f 100644 --- a/include/drivers/interrupt_controller/loapic.h +++ b/include/drivers/interrupt_controller/loapic.h @@ -39,6 +39,7 @@ #define LOAPIC_TIMER_ICR 0x380 /* Timer Initial Count Reg */ #define LOAPIC_TIMER_CCR 0x390 /* Timer Current Count Reg */ #define LOAPIC_TIMER_CONFIG 0x3e0 /* Timer Divide Config Reg */ +#define LOAPIC_SELF_IPI 0x3f0 /* Self IPI Reg, only support in X2APIC mode */ #define LOAPIC_ICR_BUSY 0x00001000 /* delivery status: 1 = busy */ diff --git a/subsys/testsuite/include/interrupt_util.h b/subsys/testsuite/include/interrupt_util.h index 09fad0cbf1f..76944c087e8 100644 --- a/subsys/testsuite/include/interrupt_util.h +++ b/subsys/testsuite/include/interrupt_util.h @@ -101,30 +101,49 @@ static inline void trigger_irq(int irq) } #elif defined(CONFIG_X86) + +#ifdef CONFIG_X2APIC #include +#define VECTOR_MASK 0xFF +#else #include +#define LOAPIC_ICR_IPI_TEST 0x00004000U +#endif #define TRIGGER_IRQ_INT(vector) __asm__ volatile("int %0" : : "i" (vector) : "memory") /* - * Write Local APIC's ICR to trigger IPI for testing + * We can emulate the interrupt by sending the IPI to + * core itself by the LOAPIC for x86 platform. + * + * In APIC mode, Write LOAPIC's ICR to trigger IPI, + * the LOAPIC_ICR_IPI_TEST 0x00004000U means: * Delivery Mode: Fixed * Destination Mode: Physical * Level: Assert * Trigger Mode: Edge * Destination Shorthand: No Shorthand * Destination: depends on cpu_id + * + * In X2APIC mode, this no longer works. We emulate the + * interrupt by writing the IA32_X2APIC_SELF_IPI MSR + * to send IPI to the core itself via LOAPIC also. + * According to SDM vol.3 chapter 10.12.11, the bit[7:0] + * for setting the vector is only needed. */ -#define LOAPIC_ICR_IPI_TEST 0x00004000U - static inline void trigger_irq(int vector) { +#ifdef CONFIG_X2APIC + x86_write_x2apic(LOAPIC_SELF_IPI, ((VECTOR_MASK & vector))); +#else + #ifdef CONFIG_SMP int cpu_id = arch_curr_cpu()->id; #else int cpu_id = 0; #endif z_loapic_ipi(cpu_id, LOAPIC_ICR_IPI_TEST, vector); +#endif /* CONFIG_X2APIC */ } #elif defined(CONFIG_ARCH_POSIX)