diff options
author | Nathan Ringo <nathan@remexre.com> | 2024-08-27 12:23:38 -0500 |
---|---|---|
committer | Nathan Ringo <nathan@remexre.com> | 2024-08-27 12:23:38 -0500 |
commit | 15fd8115739da57c6aa64da9a2ac6e0f0b7ba088 (patch) | |
tree | 28a9032f3b0a3089f5fc1e8cf7587d6803085071 /kernel/src/arch/riscv64/interrupts.rs | |
parent | 251ea035fa2338db7b001af338d65875a9bc65ad (diff) |
The start of the buddy allocator.
Diffstat (limited to 'kernel/src/arch/riscv64/interrupts.rs')
-rw-r--r-- | kernel/src/arch/riscv64/interrupts.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/kernel/src/arch/riscv64/interrupts.rs b/kernel/src/arch/riscv64/interrupts.rs new file mode 100644 index 0000000..302fc4f --- /dev/null +++ b/kernel/src/arch/riscv64/interrupts.rs @@ -0,0 +1,82 @@ +use crate::{ + drivers::riscv_timer::{set_timer, Instant}, + prelude::*, +}; +use core::{ + arch::{asm, global_asm}, + time::Duration, +}; + +/// Sets up the timer interrupt. +#[inline(never)] +pub(crate) fn example_timer() { + let now = Instant::now(); + info!("now = {now:?}"); + + let in_a_sec = now + Duration::from_secs(1); + info!("in_a_sec = {in_a_sec:?}"); + info!("setting a timer for 1s..."); + set_timer(in_a_sec); + + enable_interrupts(); +} + +/// Disables interrupts. +pub fn disable_interrupts() { + // Set SSTATUS.SIE to 0, which disables interrupts. + // + // SAFETY: Not running interrupts shouldn't be able to compromise safety. + unsafe { + asm!( + "csrc sstatus, {sie}", + sie = in(reg) (1 << 1), + options(nomem, nostack) + ); + } +} + +/// Enables interrupts. +pub fn enable_interrupts() { + // Set STVEC.BASE to the handler function, and STVEC.MODE to Direct. Since the trap_handler_asm + // has a `.align 4` before it, the lower two bits of its address should already be zero. + // + // SAFETY: Even if interrupts were already enabled, this is a valid handler. + unsafe { + asm!( + "csrw stvec, {stvec}", + stvec = in(reg) trap_handler_asm, + options(nomem, nostack) + ); + } + + // Set SSTATUS.SIE to 1, which enables interrupts. + // + // SAFETY: We just initialized STVEC, so it should be able to handle interrupts. + unsafe { + asm!( + "csrs sstatus, {sie}", + sie = in(reg) (1 << 1), + options(nomem, nostack) + ); + } +} + +fn trap_handler() { + todo!("trap_handler") +} + +// The assembly code that calls the Rust trap handler, after saving all caller-save registers +// to the stack. +global_asm! { + // Declare the handler's symbol. + ".align 4", + "trap_handler_asm:", + // TODO + "nop", + "call {trap_handler}", + trap_handler = sym trap_handler +} + +extern "C" { + fn trap_handler_asm(); +} |