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/trap.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/trap.c')
| -rw-r--r-- | kernel/trap.c | 19 |
1 files changed, 10 insertions, 9 deletions
diff --git a/kernel/trap.c b/kernel/trap.c index 84f8398..bf8a89e 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -59,12 +59,7 @@ __kernel __always_inline void exception_handler(uint64_t cause) die("Bad syscall\n"); } - // TODO: acknowledge 'sip' bit? - next_task = TASK_UNKNOWN; write(message, n); - - // TODO: is it safe to jump to idle here? Any preparation to be done? - idle(); } /* @@ -79,6 +74,9 @@ __kernel __always_inline void exception_handler(uint64_t cause) * all registers. It's probably a bit over the top since it also does that for * registers we never care on this kernel (e.g. floating point registers), but * it's convenient. + * + * TODO: once this properly works, switch it to assembly to avoid creepy + * statements like the sad 'goto end' one. */ __aligned(4) __s_interrupt __kernel void interrupt_handler(void) { @@ -87,6 +85,8 @@ __aligned(4) __s_interrupt __kernel void interrupt_handler(void) if (IS_EXCEPTION(cause)) { exception_handler(cause); + switch_to(TASK_INIT); + goto end; } if ((cause & TIMER_SCAUSE_MASK) == TIMER_SCAUSE_MASK) { @@ -101,13 +101,12 @@ __aligned(4) __s_interrupt __kernel void interrupt_handler(void) // BEHOLD! The fizz buzz logic! :D seconds_elapsed += 1; if ((seconds_elapsed % 15) == 0) { - next_task = TASK_FIZZBUZZ; + switch_to(TASK_FIZZBUZZ); } else if ((seconds_elapsed % 5) == 0) { - next_task = TASK_BUZZ; + switch_to(TASK_BUZZ); } else if ((seconds_elapsed % 3) == 0) { - next_task = TASK_FIZZ; + switch_to(TASK_FIZZ); } else { - next_task = TASK_UNKNOWN; } // Re-enable timer interrupts. @@ -122,6 +121,8 @@ __aligned(4) __s_interrupt __kernel void interrupt_handler(void) } else { printk("WARN: unknown interrupt just came in...\n"); } + +end:; } __kernel void setup_interrupts(void) |
