Skip to content

Commit 55e1c2c

Browse files
committed
Remove hart parking and add spinlock synchronization during boot for SMP
Remove the old logic that parks all secondary harts in WFI, which caused them to hang indefinitely. Instead, all harts proceed with boot. To ensure proper initialization sequence, hart 0 performs hardware setup, heap initialization, and task creation. Other harts spin-wait on a spinlock-protected flag until hart 0 finishes initialization before starting task dispatch.
1 parent c1fe6af commit 55e1c2c

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

arch/riscv/boot.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,6 @@ __attribute__((naked, section(".text.prologue"))) void _entry(void)
7070
"csrw mideleg, zero\n" /* No interrupt delegation to S-mode */
7171
"csrw medeleg, zero\n" /* No exception delegation to S-mode */
7272

73-
/* Park secondary harts (cores) - only hart 0 continues */
74-
"csrr t0, mhartid\n"
75-
"bnez t0, .Lpark_hart\n"
76-
7773
/* Set the machine trap vector (mtvec) to point to our ISR */
7874
"la t0, _isr\n"
7975
"csrw mtvec, t0\n"
@@ -87,15 +83,12 @@ __attribute__((naked, section(".text.prologue"))) void _entry(void)
8783
"csrw mie, t0\n"
8884

8985
/* Jump to the C-level main function */
86+
"csrr a0, mhartid\n"
9087
"call main\n"
9188

9289
/* If main() ever returns, it is a fatal error */
9390
"call hal_panic\n"
9491

95-
".Lpark_hart:\n"
96-
"wfi\n"
97-
"j .Lpark_hart\n"
98-
9992
: /* no outputs */
10093
: "i"(MSTATUS_MPP_MACH), "i"(MIE_MEIE), "i"(STACK_SIZE_PER_HART)
10194
: "memory");

kernel/main.c

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
#include <hal.h>
2+
#include <spinlock.h>
23
#include <lib/libc.h>
34
#include <sys/task.h>
45

56
#include "private/error.h"
67

8+
static volatile bool finish = false;
9+
static spinlock_t finish_lock = SPINLOCK_INITIALIZER;
10+
711
/* C-level entry point for the kernel.
812
*
913
* This function is called from the boot code ('_entry'). It is responsible for
@@ -12,21 +16,36 @@
1216
*
1317
* Under normal operation, this function never returns.
1418
*/
15-
int32_t main(void)
19+
int32_t main(int32_t hartid)
1620
{
1721
/* Initialize hardware abstraction layer and memory heap. */
1822
hal_hardware_init();
1923

20-
printf("Linmo kernel is starting...\n");
24+
if (hartid == 0) {
25+
printf("Linmo kernel is starting...\n");
26+
27+
mo_heap_init((void *) &_heap_start, (size_t) &_heap_size);
28+
printf("Heap initialized, %u bytes available\n",
29+
(unsigned int) (size_t) &_heap_size);
30+
31+
/* Call the application's main entry point to create initial tasks. */
32+
kcb->preemptive = (bool) app_main();
33+
printf("Scheduler mode: %s\n",
34+
kcb->preemptive ? "Preemptive" : "Cooperative");
2135

22-
mo_heap_init((void *) &_heap_start, (size_t) &_heap_size);
23-
printf("Heap initialized, %u bytes available\n",
24-
(unsigned int) (size_t) &_heap_size);
36+
spin_lock(&finish_lock);
37+
finish = true;
38+
spin_unlock(&finish_lock);
39+
}
2540

26-
/* Call the application's main entry point to create initial tasks. */
27-
kcb->preemptive = (bool) app_main();
28-
printf("Scheduler mode: %s\n",
29-
kcb->preemptive ? "Preemptive" : "Cooperative");
41+
/* Make sure hardware initialize before running the first task. */
42+
while (1) {
43+
spin_lock(&finish_lock);
44+
if (finish)
45+
break;
46+
spin_unlock(&finish_lock);
47+
}
48+
spin_unlock(&finish_lock);
3049

3150
/* Verify that the application created at least one task.
3251
* If 'kcb->task_current' is still NULL, it means mo_task_spawn was never
@@ -40,6 +59,8 @@ int32_t main(void)
4059
*/
4160
setjmp(kcb->context);
4261

62+
spin_lock(&finish_lock);
63+
4364
/* Launch the first task.
4465
* 'kcb->task_current' was set by the first call to mo_task_spawn.
4566
* This function transfers control and does not return.
@@ -48,6 +69,8 @@ int32_t main(void)
4869
if (!first_task)
4970
panic(ERR_NO_TASKS);
5071

72+
spin_unlock(&finish_lock);
73+
5174
hal_dispatch_init(first_task->context);
5275

5376
/* This line should be unreachable. */

0 commit comments

Comments
 (0)