Commit 804aa29f authored by Conor Paxton's avatar Conor Paxton Committed by Fabio Baltieri
Browse files

riscv: smp: use devicetree to map hartids to zephyr cpus



For RISC-V, the reg property of a cpu node in the devicetree describes
the low level unique ID of each hart. Using devicetree macro's, a list
of all cpus with status "okay" can be generated.

Using devicetree overlays, a hart or multiple harts can be marked as
"disabled", thus excluding them from the list. This allows platforms
that have non-zero indexed SMP capable harts to be functionally mapped
to Zephyr's sequential CPU numbering scheme.

On kernel init, if the application has MP_MAX_NUM_CPUS greater than 1,
generate the list of cpu nodes from the device tree with status "okay"
and  map the unique hartid's to zephyr cpu's

While we are at it, as the hartid is the value that gets passed to
z_riscv_secondary_cpu_init, use that as the variable name instead of
cpu_num

Signed-off-by: default avatarConor Paxton <conor.paxton@microchip.com>
parent 02391ed0
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -25,18 +25,25 @@ void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
	riscv_cpu_init[cpu_num].arg = arg;

	riscv_cpu_sp = Z_KERNEL_STACK_BUFFER(stack) + sz;
	riscv_cpu_wake_flag = cpu_num;
	riscv_cpu_wake_flag = _kernel.cpus[cpu_num].arch.hartid;

	while (riscv_cpu_wake_flag != 0U) {
		;
	}
}

void z_riscv_secondary_cpu_init(int cpu_num)
void z_riscv_secondary_cpu_init(int hartid)
{
	unsigned int i;
	unsigned int cpu_num = 0;

	for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) {
		if (_kernel.cpus[i].arch.hartid == hartid) {
			cpu_num = i;
		}
	}
	csr_write(mscratch, &_kernel.cpus[cpu_num]);
#ifdef CONFIG_SMP
	_kernel.cpus[cpu_num].arch.hartid = csr_read(mhartid);
	_kernel.cpus[cpu_num].arch.online = true;
#endif
#ifdef CONFIG_THREAD_LOCAL_STORAGE
+14 −0
Original line number Diff line number Diff line
@@ -36,6 +36,20 @@ static ALWAYS_INLINE void arch_kernel_init(void)
	_kernel.cpus[0].arch.hartid = csr_read(mhartid);
	_kernel.cpus[0].arch.online = true;
#endif
#if ((CONFIG_MP_MAX_NUM_CPUS) > 1)
	unsigned int cpu_node_list[] = {
		DT_FOREACH_CHILD_STATUS_OKAY_SEP(DT_PATH(cpus), DT_REG_ADDR, (,))
	};
	unsigned int cpu_num, hart_x;

	for (cpu_num = 1, hart_x = 0; cpu_num < arch_num_cpus(); cpu_num++) {
		if (cpu_node_list[hart_x] == _kernel.cpus[0].arch.hartid) {
			hart_x++;
		}
		_kernel.cpus[cpu_num].arch.hartid = cpu_node_list[hart_x];
		hart_x++;
	}
#endif
#ifdef CONFIG_RISCV_PMP
	z_riscv_pmp_init();
#endif
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ struct _cpu_arch {
	unsigned long user_exc_tmp0;
	unsigned long user_exc_tmp1;
#endif
#ifdef CONFIG_SMP
#if defined(CONFIG_SMP) || (CONFIG_MP_MAX_NUM_CPUS > 1)
	unsigned long hartid;
	bool online;
#endif