arm64: smp: Fix broadcast_ipi issue
This commit mainly fixes the broadcast_ipi issue when one core broadcast ipi to other cores using gic_raise_sgi. The issue doesn't affect the functionality of Zephyr SMP but will happen when Zephyr runs on Xen. Suppose Xen provides 4 CPUs to the Zephyr guest, for example, when cpu0 broadcasts ipi to the rest of the cores, the mask should be 0xE(0b1110), but for now, Zephyr will send 0xFFFE. So for Xen, it will receive a target list containing many invalid CPUs which don't exist. My solution is: to generate the target list according to the online CPUs. Signed-off-by: Jaxson Han <jaxson.han@arm.com>
This commit is contained in:
parent
539c1c9c34
commit
3122b9ed10
1 changed files with 8 additions and 1 deletions
|
@ -50,6 +50,7 @@ volatile struct boot_params __aligned(L1_CACHE_BYTES) arm64_cpu_boot_params = {
|
|||
static const uint64_t cpu_node_list[] = {
|
||||
DT_FOREACH_CHILD_STATUS_OKAY(DT_PATH(cpus), CPU_REG_ID)
|
||||
};
|
||||
static uint16_t target_list_mask;
|
||||
|
||||
extern void z_arm64_mm_init(bool is_primary_core);
|
||||
|
||||
|
@ -108,6 +109,8 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
|
|||
while (arm64_cpu_boot_params.fn) {
|
||||
wfe();
|
||||
}
|
||||
/* Set secondary cores bit mask */
|
||||
target_list_mask |= 1 << MPIDR_TO_CORE(cpu_mpid);
|
||||
printk("Secondary CPU core %d (MPID:%#llx) is up\n", cpu_num, cpu_mpid);
|
||||
}
|
||||
|
||||
|
@ -163,7 +166,8 @@ static void broadcast_ipi(unsigned int ipi)
|
|||
* Send SGI to all cores except itself
|
||||
* Note: Assume only one Cluster now.
|
||||
*/
|
||||
gic_raise_sgi(ipi, mpidr, SGIR_TGT_MASK & ~(1 << MPIDR_TO_CORE(mpidr)));
|
||||
gic_raise_sgi(ipi, mpidr, target_list_mask &
|
||||
~(1 << MPIDR_TO_CORE(mpidr)));
|
||||
}
|
||||
|
||||
void sched_ipi_handler(const void *unused)
|
||||
|
@ -219,6 +223,9 @@ static int arm64_smp_init(const struct device *dev)
|
|||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* Seting the primary core bit mask */
|
||||
target_list_mask |= 1 << MPIDR_TO_CORE(GET_MPIDR());
|
||||
|
||||
/*
|
||||
* SGI0 is use for sched ipi, this might be changed to use Kconfig
|
||||
* option
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue