-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Qemu-virt64-riscv BSP support SMP architecture #10887
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
…ng the SMP architecture. Currently, the bsp: qemu-virt64-riscv does not support the SMP architecture, and some necessary interfaces are not implemented. Solution: Add the interface declarations to make the compilation pass. Signed-off-by: Mengchen Teng <[email protected]>
…rchitecture. Tests conducted on bsp: qemu-virt64-riscv. Currently, the command line cannot start normally. This is because the SMP architecture requires scheduling information update operations; secondly, it does not yet support context switching operations within interrupts. Solution: In the two functions (rt_hw_context_switch_to and rt_hw_context_switch) in context_gcc.S, add a call to rt_cpus_lock_status_restore to update the scheduler information. For the second issue, if scheduling is triggered in an interrupt, pcpu->irq_switch_flag will be set to 1; thus, rt_scheduler_do_irq_switch is called in interrupt_gcc.S to determine whether to perform context switching. Signed-off-by: Mengchen Teng <[email protected]>
…the spinlock. The specific implementation of the spinlock is added in risc-v/virt64/interrupt.c. Due to the need for atomic operations, a new file atomic_riscv.c (copied from the common directory) is added under risc-v/common64. Signed-off-by: Mengchen Teng <[email protected]>
…e 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]>
Add IPI handling logic based on the RISC-V architecture.We handle IPI-related requests in software interrupts. Up to this point, the RISC-V 64 architecture can support the 2-core SMP mode and has passed the SMP Utest. Signed-off-by: Mengchen Teng <[email protected]>
…figuration. Add dynamic startup based on core configuration. It should be noted that to pass the SMP Utest, the maximum priority needs to be configured to 256. Signed-off-by: Mengchen Teng <[email protected]>
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
📌 Code Review Assignment🏷️ Tag: libcpu_riscvReviewers: Yaochenger Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2025-11-05 10:54 CST)
📝 Review Instructions
|
|
@Tm-C-mT you need sign CLA first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request adds SMP (Symmetric Multi-Processing) support for the RISC-V virt64 BSP. The implementation includes IPI (Inter-Processor Interrupt) handling, spinlock mechanisms, atomic operations, and multi-core initialization.
Key changes:
- Adds IPI support with dedicated descriptor array and handler functions
- Implements ticket-based spinlock for SMP synchronization
- Adds atomic operation primitives using RISC-V AMO instructions
- Implements secondary CPU initialization and boot-up logic
- Updates trap handling to support per-CPU nested trap detection
Reviewed Changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| libcpu/risc-v/virt64/interrupt.c | Adds IPI infrastructure, spinlock implementation, and interrupt priority functions |
| libcpu/risc-v/common64/trap.c | Updates for per-CPU trap nesting detection and IPI handler integration |
| libcpu/risc-v/common64/startup_gcc.S | Adds multi-hart initialization and per-CPU stack setup |
| libcpu/risc-v/common64/interrupt_gcc.S | Adds SMP-specific interrupt handling and local IRQ control |
| libcpu/risc-v/common64/cpuport.c | Adds secondary CPU entry point and context switch for SMP |
| libcpu/risc-v/common64/context_gcc.S | Adds CPU lock status restoration in context switches |
| libcpu/risc-v/common64/atomic_riscv.c | Implements RISC-V atomic operations using AMO instructions |
| bsp/qemu-virt64-riscv/run.sh | Updates to support dynamic SMP core configuration |
| bsp/qemu-virt64-riscv/qemu-dbg.sh | Updates to support dynamic SMP core configuration |
| bsp/qemu-virt64-riscv/link_cpus.lds | Defines the number of CPUs for linker |
| bsp/qemu-virt64-riscv/link.lds | Updates stack allocation for multiple CPUs |
| bsp/qemu-virt64-riscv/driver/board.c | Adds IPI initialization during board setup |
| bsp/qemu-virt64-riscv/SConstruct | Extracts CPU count from rtconfig.h and writes to linker script |
libcpu/risc-v/virt64/interrupt.c
Outdated
|
|
||
| void rt_hw_spin_lock_init(rt_hw_spinlock_t *_lock) | ||
| { | ||
| union rt_hw_spinlock_t *lock = (void *)_lock; |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug/错误: The variable lock is declared but never used in the function. The next line directly uses _lock->slock, making this cast pointless. Either use the lock variable consistently or remove it.
中文: 声明的变量 lock 从未被使用。下一行直接使用了 _lock->slock,使得这个类型转换毫无意义。要么一致地使用 lock 变量,要么删除它。
| union rt_hw_spinlock_t *lock = (void *)_lock; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been modified according to the content.
libcpu/risc-v/virt64/interrupt.c
Outdated
|
|
||
| void rt_hw_ipi_send(int ipi_vector, unsigned int cpu_mask) | ||
| { | ||
| int cpuid = cpu_mask & -cpu_mask; // get the lowest set bit |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug/错误: The logic to extract the CPU ID from cpu_mask is incorrect. The expression cpu_mask & -cpu_mask isolates the lowest set bit (e.g., 0b0100 becomes 0b0100), but this is not the bit position. For example, if cpu_mask = 4 (bit 2), the result is 4, not 2. This will cause an out-of-bounds array access. Use __builtin_ctz(cpu_mask) to get the bit position.
中文: 从 cpu_mask 提取 CPU ID 的逻辑不正确。表达式 cpu_mask & -cpu_mask 会分离出最低位的 1(例如 0b0100 变成 0b0100),但这不是位位置。例如,如果 cpu_mask = 4(第 2 位),结果是 4 而不是 2。这将导致数组越界访问。应使用 __builtin_ctz(cpu_mask) 获取位位置。
| int cpuid = cpu_mask & -cpu_mask; // get the lowest set bit | |
| int cpuid = __builtin_ctz(cpu_mask); // get the bit position of the lowest set bit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been modified according to the content.
libcpu/risc-v/common64/cpuport.c
Outdated
| return 0; | ||
| #else | ||
| /* Currently, the hartid is stored in the satp register. */ | ||
| uint32_t hart_id; |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug/错误: Using uint32_t for hart_id is problematic on 64-bit systems. The satp CSR is 64-bit on RV64 systems. Using a 32-bit variable will truncate the value, potentially losing important bits. Change to rt_ubase_t or uint64_t.
中文: 使用 uint32_t 作为 hart_id 在 64 位系统上存在问题。在 RV64 系统上,satp CSR 是 64 位的。使用 32 位变量会截断值,可能丢失重要位。应改为 rt_ubase_t 或 uint64_t。
| uint32_t hart_id; | |
| rt_ubase_t hart_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been modified according to the content.
| li t0, __STACKSIZE__ | ||
| add sp, sp, t0 | ||
| #else | ||
| csrw satp, a0 /* Currently, the hartid is stored in the satp register. */ |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Best Practices/最佳实践: Storing the hartid in the satp register is unconventional and potentially problematic. The satp CSR is designed for address translation control and may be modified by MMU initialization code. Consider using a dedicated memory location or a different CSR (like sscratch temporarily, or a memory-mapped per-CPU data structure).
中文: 将 hartid 存储在 satp 寄存器中是非常规的,且可能存在问题。satp CSR 是为地址转换控制设计的,可能会被 MMU 初始化代码修改。建议使用专用的内存位置或不同的 CSR(如临时使用 sscratch,或使用内存映射的每 CPU 数据结构)。
| csrw satp, a0 /* Currently, the hartid is stored in the satp register. */ | |
| /* Removed storing hartid in satp register; hartid is stored in boot_hartid memory location. */ |
libcpu/risc-v/common64/cpuport.c
Outdated
| #ifdef RT_USING_SMP | ||
| /* ipi init */ | ||
| rt_hw_ipi_init(); | ||
| #endif /* RT_USING_SMP */ |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maintainability/可维护性: Redundant nested #ifdef RT_USING_SMP check inside secondary_cpu_entry() which is already within an #ifdef RT_USING_SMP block (line 159). Remove the inner conditional.
中文: 在 secondary_cpu_entry() 中存在冗余的 #ifdef RT_USING_SMP 嵌套检查,而该函数已经在 #ifdef RT_USING_SMP 块内(第 159 行)。应删除内部的条件编译。
| #ifdef RT_USING_SMP | |
| /* ipi init */ | |
| rt_hw_ipi_init(); | |
| #endif /* RT_USING_SMP */ | |
| /* ipi init */ | |
| rt_hw_ipi_init(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been modified according to the content.
libcpu/risc-v/common64/cpuport.c
Outdated
| int hart, ret; | ||
|
|
||
| /* translate kernel virtual _start to physical address */ | ||
| entry_pa = (rt_uint64_t)&_start;//(rt_uint64_t)rt_kmem_v2p((void *)&_start); |
Copilot
AI
Nov 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maintainability/可维护性: Commented-out code should be removed. If virtual-to-physical translation is needed, either implement it or add a TODO comment explaining why it's not needed currently.
中文: 应删除被注释的代码。如果需要虚拟地址到物理地址的转换,要么实现它,要么添加 TODO 注释解释为何当前不需要。
| entry_pa = (rt_uint64_t)&_start;//(rt_uint64_t)rt_kmem_v2p((void *)&_start); | |
| entry_pa = (rt_uint64_t)&_start; /* TODO: Virtual-to-physical translation is not needed here because &_start is already a physical address on this platform. */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It has been modified according to the content.
|
hartid目前保存在satp寄存器,是asid部分么,如果是这样,smart版本会受影响 |
8561395 to
d892bf8
Compare
The CLA has now been signed. |
Fix issues with non-standard formatting Signed-off-by: Mengchen Teng <[email protected]>
d892bf8 to
1df567e
Compare
拉取/合并请求描述:(PR description)
[
为什么提交这份PR (why to submit this PR)
目前qemu-virt64-riscv BSP不支持SMP模式下的运行,想让riscv64支持SMP架构。
这种修改方式是否合理?如不合理,修改后是否有可能被接受?
你的解决方案是什么 (what is your solution)
1、添加SMP架构下的必要接口,详见commit: 6c0a7d1
2、解决使能SMP后,hart为1时的启动挂死问题。添加rt_cpus_lock_status_restore与中断中的调度逻辑。详见commit: 7948f50
3、解决hart=2时的多核启动问题。hartid目前保存在了satp寄存器中,栈区地址根据hartid分配。并实现rt_hw_secondary_cpu_up与secondary_cpu_entry。详见commit: 402ec68
4、实现自旋锁及IPI处理逻辑。详见commit: c7cbe2e 及 8386d29。
5、qemu-virt64-riscv BSP根据config配置动态启动。详见commit: 7a770ce
请提供验证的bsp和config (provide the config and bsp)
]
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up