diff options
| author | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-24 22:07:51 +0100 |
|---|---|---|
| committer | Miquel Sabaté Solà <mikisabate@gmail.com> | 2024-11-24 22:22:48 +0100 |
| commit | 192208770d3866838a450462dd4b1fc8e2b5c91a (patch) | |
| tree | ec3f929b77d407ef57634cd917c04a13d614c8c8 /kernel/main.c | |
| parent | 7f6b234625a53d2ceb9ec80dc0172aac1cedb358 (diff) | |
| download | fbos-192208770d3866838a450462dd4b1fc8e2b5c91a.tar.gz fbos-192208770d3866838a450462dd4b1fc8e2b5c91a.zip | |
Simplify scheduling by introducing an init process
Scheduling is easier if there is an init process which does nothing.
This way we don't have to perform hacks in order to idle in S privilege
mode while touching special registers in weird ways.
For now this process is kind of costly since 'wfi' is not accepted in
this context, but this can be further tuned down in the future by
setting TW=1 on 'mstatus', or by handling the exception and allowing it
if it comes from the proper process.
All of that being said, there is still work to be done as things fail
when optimitzations are on.
Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
Diffstat (limited to 'kernel/main.c')
| -rw-r--r-- | kernel/main.c | 16 |
1 files changed, 2 insertions, 14 deletions
diff --git a/kernel/main.c b/kernel/main.c index 4ed99b5..ba4ada0 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -13,9 +13,7 @@ struct task_struct tasks[4] = { [TASK_FIZZBUZZ] = { .stack = init_stack[3], .addr = nullptr, .entry_offset = 0, }, }; -int next_task; - -// TODO: this feels really brittle +// TODO __kernel void switch_to(int task_id) { const char *ddr = (const char *)tasks[task_id].addr + tasks[task_id].entry_offset; @@ -23,7 +21,6 @@ __kernel void switch_to(int task_id) asm volatile("csrc sstatus, %[mask]" : : [mask] "r"(1 << 8)); asm volatile("mv ra, %0" : : "r"(ddr)); asm volatile("csrw sepc, ra"); - asm volatile("sret"); } /* @@ -39,23 +36,14 @@ __noreturn __kernel void start_kernel(void *dtb) struct initrd_addr addr = find_dt_initrd_addr(dtb); extract_initrd((unsigned char *)addr.start, addr.end - addr.start); - next_task = TASK_UNKNOWN; - // At this point everything has already been handled: setup the interrupt // vector and enable the timer to start ticking and scheduling the three // tasks at hand. seconds_elapsed = 0; setup_interrupts(); - idle(); -} - -__noreturn __kernel void idle(void) -{ + // Loop indefinitely while preserving power. for (;;) { - if (next_task != TASK_UNKNOWN && next_task != TASK_INIT) { - switch_to(next_task); - } asm volatile("wfi"); } } |
