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 <charles.youse@intel.com>
This commit is contained in:
Charles E. Youse 2019-09-30 13:28:36 -04:00 committed by Anas Nashif
parent 74e3717af6
commit 66510db98c
5 changed files with 53 additions and 1 deletions

View File

@ -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"

View File

@ -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,

View File

@ -4,6 +4,7 @@
*/
#include <kernel.h>
#include <ksched.h>
#include <arch/cpu.h>
#include <kernel_arch_data.h>
#include <drivers/interrupt_controller/sysapic.h>
@ -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

View File

@ -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();
}

View File

@ -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 <drivers/interrupt_controller/loapic.h>
/*
* 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_ */