Skip to content

Commit 0b3136c

Browse files
povergoingcarlescufi
authored andcommitted
arch: arm64: Add cpu_map to map cpu id and mpid
cpu_node_list does not hold the corrent mapping of cpu id and mpid when core booting sequence does not follow the DTS cpu node sequence. This will cause an issue that sgi cannot deliver to the right target. Add the cpu_map array to hold the corrent mapping between cpu id and mpid. Signed-off-by: Jaxson Han <[email protected]>
1 parent f03a4ce commit 0b3136c

File tree

1 file changed

+22
-5
lines changed

1 file changed

+22
-5
lines changed

arch/arm64/core/smp.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <zephyr/irq.h>
2727
#include "boot.h"
2828

29+
#define INV_MPID UINT64_MAX
30+
2931
#define SGI_SCHED_IPI 0
3032
#define SGI_MMCFG_IPI 1
3133
#define SGI_FPU_IPI 2
@@ -50,6 +52,11 @@ static const uint64_t cpu_node_list[] = {
5052
DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,))
5153
};
5254

55+
/* cpu_map saves the maping of core id and mpid */
56+
static uint64_t cpu_map[CONFIG_MP_MAX_NUM_CPUS] = {
57+
[0 ... (CONFIG_MP_MAX_NUM_CPUS - 1)] = INV_MPID
58+
};
59+
5360
extern void z_arm64_mm_init(bool is_primary_core);
5461

5562
/* Called from Zephyr initialization */
@@ -106,6 +113,9 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
106113
while (arm64_cpu_boot_params.fn) {
107114
wfe();
108115
}
116+
117+
cpu_map[cpu_num] = cpu_mpid;
118+
109119
printk("Secondary CPU core %d (MPID:%#llx) is up\n", cpu_num, cpu_mpid);
110120
}
111121

@@ -166,13 +176,14 @@ static void broadcast_ipi(unsigned int ipi)
166176
unsigned int num_cpus = arch_num_cpus();
167177

168178
for (int i = 0; i < num_cpus; i++) {
169-
uint64_t target_mpidr = cpu_node_list[i];
170-
uint8_t aff0 = MPIDR_AFFLVL(target_mpidr, 0);
179+
uint64_t target_mpidr = cpu_map[i];
180+
uint8_t aff0;
171181

172-
if (mpidr == target_mpidr) {
182+
if (mpidr == target_mpidr || mpidr == INV_MPID) {
173183
continue;
174184
}
175185

186+
aff0 = MPIDR_AFFLVL(target_mpidr, 0);
176187
gic_raise_sgi(ipi, target_mpidr, 1 << aff0);
177188
}
178189
}
@@ -220,9 +231,14 @@ void flush_fpu_ipi_handler(const void *unused)
220231

221232
void z_arm64_flush_fpu_ipi(unsigned int cpu)
222233
{
223-
const uint64_t mpidr = cpu_node_list[cpu];
224-
uint8_t aff0 = MPIDR_AFFLVL(mpidr, 0);
234+
const uint64_t mpidr = cpu_map[cpu];
235+
uint8_t aff0;
236+
237+
if (mpidr == INV_MPID) {
238+
return;
239+
}
225240

241+
aff0 = MPIDR_AFFLVL(mpidr, 0);
226242
gic_raise_sgi(SGI_FPU_IPI, mpidr, 1 << aff0);
227243
}
228244

@@ -248,6 +264,7 @@ void arch_spin_relax(void)
248264

249265
static int arm64_smp_init(void)
250266
{
267+
cpu_map[0] = MPIDR_TO_CORE(GET_MPIDR());
251268

252269
/*
253270
* SGI0 is use for sched ipi, this might be changed to use Kconfig

0 commit comments

Comments
 (0)