Skip to content

Commit 402ec68

Browse files
committed
[libcpu-riscv]: [common64 virt64]: Add the dual-core feature under the SMP architecture.
Currently, it does not support operation with two or more cores. Solution: Since the system runs in S-mode and does not support access to the mhartid register, the hartid is currently stored in the satp register (this register is not used when the bsp qemu-virt64-riscv runs RT-Thread). Additionally, logic for storing boot_hartid and multi-core initialization logic for the sp pointer have been added in startup_gcc.S. Logic for secondary core wake-up and entry has been added in cpuport.c. Signed-off-by: Mengchen Teng <[email protected]>
1 parent c7cbe2e commit 402ec68

File tree

3 files changed

+68
-3
lines changed

3 files changed

+68
-3
lines changed

bsp/qemu-virt64-riscv/run.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if [ ! -f $path_image ]; then
2424
exit
2525
fi
2626

27-
qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin \
27+
qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin -smp 2 \
2828
-drive if=none,file=$path_image,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
2929
-netdev user,id=tap0 -device virtio-net-device,netdev=tap0,bus=virtio-mmio-bus.1 \
3030
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0

libcpu/risc-v/common64/cpuport.c

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,14 @@ void *_rt_hw_stack_init(rt_ubase_t *sp, rt_ubase_t ra, rt_ubase_t sstatus)
6464

6565
int rt_hw_cpu_id(void)
6666
{
67+
#ifndef RT_USING_SMP
6768
return 0;
69+
#else
70+
/* Currently, the hartid is stored in the satp register. */
71+
uint32_t hart_id;
72+
asm volatile ("csrr %0, satp" : "=r"(hart_id));
73+
return hart_id;
74+
#endif /* RT_USING_SMP */
6875
}
6976

7077
/**
@@ -151,13 +158,39 @@ void rt_hw_set_process_id(int pid)
151158
}
152159

153160
#ifdef RT_USING_SMP
161+
extern void _start(void);
162+
extern int boot_hartid;
163+
/* Boot secondary harts using the SBI HSM hart_start call. */
154164
void rt_hw_secondary_cpu_up(void)
155165
{
156-
166+
rt_uint64_t entry_pa;
167+
int hart, ret;
168+
169+
/* translate kernel virtual _start to physical address */
170+
entry_pa = (rt_uint64_t)&_start;//(rt_uint64_t)rt_kmem_v2p((void *)&_start);
171+
172+
for (hart = 0; hart < RT_CPUS_NR; hart++)
173+
{
174+
if (hart == boot_hartid) continue;
175+
176+
ret = sbi_hsm_hart_start((unsigned long)hart,
177+
(unsigned long)entry_pa,
178+
0UL);
179+
if (ret)
180+
{
181+
rt_kprintf("sbi_hsm_hart_start failed for hart %d: %d\n", hart, ret);
182+
}
183+
}
157184
}
158185

159186
void secondary_cpu_entry(void)
160187
{
161-
188+
/* The PLIC peripheral interrupts are currently handled by the boot_hart. */
189+
/* Enable the Supervisor-Timer bit in SIE */
190+
rt_hw_tick_init();
191+
192+
rt_hw_spin_lock(&_cpus_lock);
193+
/* invoke system scheduler start for secondary CPU */
194+
rt_system_scheduler_start();
162195
}
163196
#endif /* RT_USING_SMP */

libcpu/risc-v/common64/startup_gcc.S

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,19 @@ _start:
3232
1:
3333
/* save hartid */
3434
la t0, boot_hartid /* global varible rt_boot_hartid */
35+
#ifdef RT_USING_SMP
36+
lw t2, (t0)
37+
li t3, 0xdeadbeef
38+
li t4, 0xffffffff
39+
and t2, t2, t4 /* Extract the lower 32 bits. */
40+
bne t2, t3, system_init /* If the current value is 0xdeadbeef, skip the boot_hartid assignment operation. */
41+
#endif
3542
mv t1, a0 /* get hartid in S-mode frome a0 register */
3643
sw t1, (t0) /* store t1 register low 4 bits in memory address which is stored in t0 */
3744

45+
#ifdef RT_USING_SMP
46+
system_init:
47+
#endif
3848
/* clear Interrupt Registers */
3949
csrw sie, 0
4050
csrw sip, 0
@@ -51,7 +61,10 @@ _start:
5161
li x7, 0
5262
li x8, 0
5363
li x9, 0
64+
#ifndef RT_USING_SMP
65+
/* In the SMP architecture, a0 will be used again later */
5466
li x10,0
67+
#endif
5568
li x11,0
5669
li x12,0
5770
li x13,0
@@ -85,10 +98,29 @@ _start:
8598
la gp, __global_pointer$
8699
.option pop
87100

101+
#ifndef RT_USING_SMP
88102
/* removed SMP support here */
89103
la sp, __stack_start__
90104
li t0, __STACKSIZE__
91105
add sp, sp, t0
106+
#else
107+
csrw satp, a0 /* Currently, the hartid is stored in the satp register. */
108+
/* Initialize the sp pointer according to different hartids. */
109+
mv t0, a0
110+
/* calculate stack offset: hartid * __STACKSIZE__ */
111+
li t1, __STACKSIZE__
112+
mul t0, t0, t1 /* t0 = hartid * __STACKSIZE__ */
113+
114+
/* set stack pointer */
115+
la sp, __stack_start__
116+
add sp, sp, t0 /* sp = __stack_start__ + hartid * __STACKSIZE__ */
117+
add sp, sp, t1 /* sp += __STACKSIZE__ (point to stack top) */
118+
119+
mv t0, a0
120+
lw t1, boot_hartid
121+
bne t0, t1, secondary_cpu_entry
122+
li x10,0 /* Clear the a0 register. */
123+
#endif /* RT_USING_SMP */
92124

93125
/**
94126
* sscratch is always zero on kernel mode

0 commit comments

Comments
 (0)