From 66510db98ca6ffb217d268c6e36df83e2ea84133 Mon Sep 17 00:00:00 2001 From: "Charles E. Youse" Date: Mon, 30 Sep 2019 13:28:36 -0400 Subject: [PATCH] arch/x86: (Intel64) add scheduler IPI support Add z_arch_sched_ipi() and such to enable scheduler IPIs when SMP. Signed-off-by: Charles E. Youse --- arch/x86/Kconfig | 3 ++- arch/x86/core/Kconfig.intel64 | 6 +++++ arch/x86/core/intel64/irq.c | 16 +++++++++++++ arch/x86/core/prep_c.c | 4 ++++ arch/x86/include/intel64/kernel_arch_func.h | 25 +++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 8d10d3098d1..19c989d5925 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -45,8 +45,9 @@ config X86_LONGMODE prompt "Run in long (64-bit) mode" default n select 64BIT - select USE_SWITCH_SUPPORTED select USE_SWITCH + select USE_SWITCH_SUPPORTED + select SCHED_IPI_SUPPORTED config MAX_IRQ_LINES int "Number of IRQ lines" diff --git a/arch/x86/core/Kconfig.intel64 b/arch/x86/core/Kconfig.intel64 index 3887bb2daf3..5fdac6cda75 100644 --- a/arch/x86/core/Kconfig.intel64 +++ b/arch/x86/core/Kconfig.intel64 @@ -32,6 +32,12 @@ config EXCEPTION_STACK_SIZE support limited call-tree depth and must fit into the low core, so they are typically smaller than the ISR stacks. +config SCHED_IPI_VECTOR + int "IDT vector to use for scheduler IPI" + default 33 + range 33 255 + depends on SMP + # We should really only have to provide one of the following two values, # but a bug in the Zephyr SDK for x86 precludes the use of division in # the assembler. For now, we require that these values be specified manually, diff --git a/arch/x86/core/intel64/irq.c b/arch/x86/core/intel64/irq.c index c0044dd1729..5847e15ee91 100644 --- a/arch/x86/core/intel64/irq.c +++ b/arch/x86/core/intel64/irq.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -103,3 +104,18 @@ void z_arch_irq_offload(irq_offload_routine_t routine, void *parameter) } #endif /* CONFIG_IRQ_OFFLOAD */ + +#if defined(CONFIG_SMP) + +void z_x86_ipi_setup(void) +{ + /* + * z_sched_ipi() doesn't have the same signature as a typical ISR, so + * we fudge it with a cast. the argument is ignored, no harm done. + */ + + x86_irq_funcs[CONFIG_SCHED_IPI_VECTOR - IV_IRQS] = + (void *) z_sched_ipi; +} + +#endif diff --git a/arch/x86/core/prep_c.c b/arch/x86/core/prep_c.c index b7ce0777330..19e1f49285c 100644 --- a/arch/x86/core/prep_c.c +++ b/arch/x86/core/prep_c.c @@ -42,5 +42,9 @@ FUNC_NORETURN void z_x86_prep_c(int unused, struct multiboot_info *info) true); #endif +#if defined(CONFIG_SMP) + z_x86_ipi_setup(); +#endif + z_cstart(); } diff --git a/arch/x86/include/intel64/kernel_arch_func.h b/arch/x86/include/intel64/kernel_arch_func.h index 2500393081c..863a138e5d6 100644 --- a/arch/x86/include/intel64/kernel_arch_func.h +++ b/arch/x86/include/intel64/kernel_arch_func.h @@ -10,6 +10,14 @@ extern void z_arch_switch(void *switch_to, void **switched_from); +/** + * @brief Initialize scheduler IPI vector. + * + * Called in early BSP boot to set up scheduler IPI handling. + */ + +extern void z_x86_ipi_setup(void); + static inline void z_arch_kernel_init(void) { /* nothing */; @@ -26,6 +34,23 @@ static inline struct _cpu *z_arch_curr_cpu(void) return cpu; } +#if defined(CONFIG_SMP) && defined(CONFIG_SCHED_IPI_SUPPORTED) + +#include + +/* + * it is not clear exactly how/where/why to abstract this, as it + * assumes the use of a local APIC (but there's no other mechanism). + */ + +static inline void z_arch_sched_ipi(void) +{ + z_loapic_ipi(0, LOAPIC_ICR_IPI_OTHERS, CONFIG_SCHED_IPI_VECTOR); +} + +#endif + + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_ARCH_X86_INCLUDE_INTEL64_KERNEL_ARCH_FUNC_H_ */