diff --git a/kernel/rustkernel/src/arch/cpu.rs b/kernel/rustkernel/src/arch/cpu.rs deleted file mode 100644 index deca519..0000000 --- a/kernel/rustkernel/src/arch/cpu.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Architecture-agnostic CPU functions. - -#[cfg(target_arch = "riscv64")] -pub use super::riscv::cpu::cpu_id; diff --git a/kernel/rustkernel/src/arch/interrupt.rs b/kernel/rustkernel/src/arch/interrupt.rs deleted file mode 100644 index 7f13c0f..0000000 --- a/kernel/rustkernel/src/arch/interrupt.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Architecture-agnostic interrupt handling. - -#[cfg(target_arch = "riscv64")] -pub use super::riscv::{ - asm::{ - intr_get as interrupts_enabled, intr_off as disable_interrupts, - intr_on as enable_interrupts, - }, - plic::{ - plic_claim as handle_interrupt, plic_complete as complete_interrupt, plicinit as init, - plicinithart as inithart, - }, -}; diff --git a/kernel/rustkernel/src/arch/mem.rs b/kernel/rustkernel/src/arch/mem.rs deleted file mode 100644 index eb40b72..0000000 --- a/kernel/rustkernel/src/arch/mem.rs +++ /dev/null @@ -1,19 +0,0 @@ -//! Architecture-agnostic memory management. - -#[cfg(target_arch = "riscv64")] -pub use super::riscv::{ - asm::sfence_vma as flush_cached_pages, - mem::{ - Pagetable, PagetableEntry, KERNEL_BASE, PAGE_SIZE, PHYSICAL_END, TRAMPOLINE, TRAPFRAME, - PTE_V, PTE_R, PTE_W, PTE_X, PTE_U, - VIRTUAL_MAX, - }, -}; - -pub fn round_up_page(size: usize) -> usize { - (size + PAGE_SIZE - 1) & !(PAGE_SIZE - 1) -} - -pub fn round_down_page(addr: usize) -> usize { - addr & !(PAGE_SIZE - 1) -} diff --git a/kernel/rustkernel/src/arch/mod.rs b/kernel/rustkernel/src/arch/mod.rs index 763a3cf..31b402b 100644 --- a/kernel/rustkernel/src/arch/mod.rs +++ b/kernel/rustkernel/src/arch/mod.rs @@ -3,7 +3,52 @@ pub mod riscv; #[cfg(target_arch = "riscv64")] pub use riscv::hardware; -pub mod cpu; -pub mod interrupt; -pub mod mem; -pub mod power; +pub mod trap; + +pub mod cpu { + #[cfg(target_arch = "riscv64")] + pub use super::riscv::cpu::cpu_id; +} + +pub mod interrupt { + #[cfg(target_arch = "riscv64")] + pub use super::riscv::{ + asm::{ + intr_get as interrupts_enabled, intr_off as disable_interrupts, + intr_on as enable_interrupts, + }, + plic::{ + plic_claim as handle_interrupt, plic_complete as complete_interrupt, plicinit as init, + plicinithart as inithart, + }, + }; +} + +pub mod mem { + #[cfg(target_arch = "riscv64")] + pub use super::riscv::{ + asm::sfence_vma as flush_cached_pages, + mem::{ + Pagetable, PagetableEntry, KERNEL_BASE, PAGE_SIZE, PHYSICAL_END, PTE_R, PTE_U, PTE_V, + PTE_W, PTE_X, TRAMPOLINE, TRAPFRAME, VIRTUAL_MAX, + }, + }; + + pub fn round_up_page(size: usize) -> usize { + (size + PAGE_SIZE - 1) & !(PAGE_SIZE - 1) + } + + pub fn round_down_page(addr: usize) -> usize { + addr & !(PAGE_SIZE - 1) + } +} + +pub mod power { + #[cfg(target_arch = "riscv64")] + pub use super::riscv::power::shutdown; +} + +pub mod clock { + #[cfg(target_arch = "riscv64")] + pub use super::riscv::trap::CLOCK_TICKS; +} diff --git a/kernel/rustkernel/src/arch/power.rs b/kernel/rustkernel/src/arch/power.rs deleted file mode 100644 index a4eeaef..0000000 --- a/kernel/rustkernel/src/arch/power.rs +++ /dev/null @@ -1,4 +0,0 @@ -//! Architecture-agnostic power handling. - -#[cfg(target_arch = "riscv64")] -pub use super::riscv::power::shutdown; diff --git a/kernel/rustkernel/src/arch/riscv/mod.rs b/kernel/rustkernel/src/arch/riscv/mod.rs index 15778a2..b4c90d2 100644 --- a/kernel/rustkernel/src/arch/riscv/mod.rs +++ b/kernel/rustkernel/src/arch/riscv/mod.rs @@ -1,11 +1,12 @@ pub mod asm; pub mod clint; pub mod cpu; -pub mod mem; pub mod hardware; +pub mod mem; pub mod plic; pub mod power; pub mod start; +pub mod trap; pub use mem::make_satp; diff --git a/kernel/rustkernel/src/trap.rs b/kernel/rustkernel/src/arch/riscv/trap.rs similarity index 71% rename from kernel/rustkernel/src/trap.rs rename to kernel/rustkernel/src/arch/riscv/trap.rs index 6346e11..9395dd7 100644 --- a/kernel/rustkernel/src/trap.rs +++ b/kernel/rustkernel/src/arch/riscv/trap.rs @@ -1,9 +1,9 @@ +use super::{asm, mem::make_satp, SSTATUS_SPIE, SSTATUS_SPP}; use crate::{ arch::{ - self, - mem::{PAGE_SIZE, TRAMPOLINE}, hardware::{UART0_IRQ, VIRTIO0_IRQ}, - riscv::{asm, SSTATUS_SPP, SSTATUS_SPIE, mem::make_satp}, + interrupt, + mem::{PAGE_SIZE, TRAMPOLINE}, }, println, proc::{ @@ -54,7 +54,7 @@ pub unsafe fn devintr() -> i32 { // This is a supervisor external interrupt, via PLIC. // IRQ indicates which device interrupted. - let irq = arch::interrupt::handle_interrupt(); + let irq = interrupt::handle_interrupt(); if irq == UART0_IRQ { crate::console::uart::UART0.interrupt(); @@ -68,7 +68,7 @@ pub unsafe fn devintr() -> i32 { // interrupt at a time; tell the PLIC the device is // now allowed to interrupt again. if irq > 0 { - arch::interrupt::complete_interrupt(irq); + interrupt::complete_interrupt(irq); } 1 @@ -90,46 +90,6 @@ pub unsafe fn devintr() -> i32 { } } -#[derive(Default)] -pub struct InterruptBlocker; -impl InterruptBlocker { - pub fn new() -> InterruptBlocker { - unsafe { - let interrupts_before = arch::interrupt::interrupts_enabled(); - let cpu = Cpu::current(); - - arch::interrupt::disable_interrupts(); - - if cpu.interrupt_disable_layers == 0 { - cpu.previous_interrupts_enabled = interrupts_before; - } - cpu.interrupt_disable_layers += 1; - // crate::sync::spinlock::push_off(); - } - InterruptBlocker - } -} -impl core::ops::Drop for InterruptBlocker { - fn drop(&mut self) { - unsafe { - let cpu = Cpu::current(); - - if arch::interrupt::interrupts_enabled() == 1 || cpu.interrupt_disable_layers < 1 { - // panic!("pop_off mismatched"); - return; - } - - cpu.interrupt_disable_layers -= 1; - - if cpu.interrupt_disable_layers == 0 && cpu.previous_interrupts_enabled == 1 { - arch::interrupt::enable_interrupts(); - } - // crate::sync::spinlock::pop_off(); - } - } -} -impl !Send for InterruptBlocker {} - /// Return to user space #[no_mangle] pub unsafe extern "C" fn usertrapret() { @@ -138,7 +98,7 @@ pub unsafe extern "C" fn usertrapret() { // We're about to switch the destination of traps from // kerneltrap() to usertrap(), so turn off interrupts until // we're back in user space, where usertrap() is correct. - arch::interrupt::disable_interrupts(); + interrupt::disable_interrupts(); // Send syscalls, interrupts, and exceptions to uservec in trampoline.S let trampoline_uservec = @@ -193,13 +153,18 @@ pub unsafe extern "C" fn kerneltrap() { if sstatus & SSTATUS_SPP == 0 { panic!("kerneltrap: not from supervisor mode"); - } else if arch::interrupt::interrupts_enabled() != 0 { + } else if interrupt::interrupts_enabled() != 0 { panic!("kerneltrap: interrupts enabled"); } let which_dev = devintr(); if which_dev == 0 { - println!("scause {}\nsepc={} stval={}", scause, asm::r_sepc(), asm::r_stval()); + println!( + "scause {}\nsepc={} stval={}", + scause, + asm::r_sepc(), + asm::r_stval() + ); panic!("kerneltrap"); } else if which_dev == 2 && Process::current().is_some() @@ -246,7 +211,7 @@ pub unsafe extern "C" fn usertrap() { // An interrupt will change sepc, scause, and sstatus, // so enable only now that we're done with those registers. - arch::interrupt::enable_interrupts(); + interrupt::enable_interrupts(); syscall(); } @@ -274,35 +239,3 @@ pub unsafe extern "C" fn usertrap() { usertrapret(); } - -// push_intr_off/pop_intr_off are like intr_off()/intr_on() except that they are matched: -// it takes two pop_intr_off()s to undo two push_intr_off()s. Also, if interrupts -// are initially off, then push_intr_off, pop_intr_off leaves them off. - -pub unsafe fn push_intr_off() { - let old = arch::interrupt::interrupts_enabled(); - let cpu = Cpu::current(); - - arch::interrupt::disable_interrupts(); - if cpu.interrupt_disable_layers == 0 { - cpu.previous_interrupts_enabled = old; - } - cpu.interrupt_disable_layers += 1; -} -pub unsafe fn pop_intr_off() { - let cpu = Cpu::current(); - - if arch::interrupt::interrupts_enabled() == 1 { - // crate::panic_byte(b'0'); - panic!("pop_intr_off - interruptible"); - } else if cpu.interrupt_disable_layers < 1 { - // crate::panic_byte(b'1'); - panic!("pop_intr_off"); - } - - cpu.interrupt_disable_layers -= 1; - - if cpu.interrupt_disable_layers == 0 && cpu.previous_interrupts_enabled == 1 { - arch::interrupt::enable_interrupts(); - } -} diff --git a/kernel/rustkernel/src/arch/trap.rs b/kernel/rustkernel/src/arch/trap.rs new file mode 100644 index 0000000..8c0454c --- /dev/null +++ b/kernel/rustkernel/src/arch/trap.rs @@ -0,0 +1,75 @@ +//! Architecture-agnostic trap handling. + +#[cfg(target_arch = "riscv64")] +pub use super::riscv::trap::trapinithart as inithart; + +use super::interrupt; +use crate::proc::cpu::Cpu; + +#[derive(Default)] +pub struct InterruptBlocker; +impl InterruptBlocker { + pub fn new() -> InterruptBlocker { + unsafe { + let interrupts_before = interrupt::interrupts_enabled(); + let cpu = Cpu::current(); + + interrupt::disable_interrupts(); + + if cpu.interrupt_disable_layers == 0 { + cpu.previous_interrupts_enabled = interrupts_before; + } + cpu.interrupt_disable_layers += 1; + // crate::sync::spinlock::push_off(); + } + InterruptBlocker + } +} +impl core::ops::Drop for InterruptBlocker { + fn drop(&mut self) { + unsafe { + let cpu = Cpu::current(); + + if interrupt::interrupts_enabled() == 1 || cpu.interrupt_disable_layers < 1 { + // panic!("pop_off mismatched"); + return; + } + + cpu.interrupt_disable_layers -= 1; + + if cpu.interrupt_disable_layers == 0 && cpu.previous_interrupts_enabled == 1 { + interrupt::enable_interrupts(); + } + // crate::sync::spinlock::pop_off(); + } + } +} +impl !Send for InterruptBlocker {} + +pub unsafe fn push_intr_off() { + let old = interrupt::interrupts_enabled(); + let cpu = Cpu::current(); + + interrupt::disable_interrupts(); + if cpu.interrupt_disable_layers == 0 { + cpu.previous_interrupts_enabled = old; + } + cpu.interrupt_disable_layers += 1; +} +pub unsafe fn pop_intr_off() { + let cpu = Cpu::current(); + + if interrupt::interrupts_enabled() == 1 { + // crate::panic_byte(b'0'); + panic!("pop_intr_off - interruptible"); + } else if cpu.interrupt_disable_layers < 1 { + // crate::panic_byte(b'1'); + panic!("pop_intr_off"); + } + + cpu.interrupt_disable_layers -= 1; + + if cpu.interrupt_disable_layers == 0 && cpu.previous_interrupts_enabled == 1 { + interrupt::enable_interrupts(); + } +} diff --git a/kernel/rustkernel/src/console/uart.rs b/kernel/rustkernel/src/console/uart.rs index 1c46051..8540962 100644 --- a/kernel/rustkernel/src/console/uart.rs +++ b/kernel/rustkernel/src/console/uart.rs @@ -2,8 +2,8 @@ #![allow(non_upper_case_globals)] use crate::{ - console::consoleintr, proc::scheduler::wakeup, queue::Queue, sync::mutex::Mutex, - trap::InterruptBlocker, + arch::trap::InterruptBlocker, console::consoleintr, proc::scheduler::wakeup, queue::Queue, + sync::mutex::Mutex, }; use core::ptr::addr_of; diff --git a/kernel/rustkernel/src/lib.rs b/kernel/rustkernel/src/lib.rs index 2d72fb2..5f261ed 100644 --- a/kernel/rustkernel/src/lib.rs +++ b/kernel/rustkernel/src/lib.rs @@ -18,7 +18,6 @@ mod queue; mod string; mod sync; mod syscall; -mod trap; use crate::{proc::cpu::Cpu, sync::mutex::Mutex}; use core::ffi::{c_char, CStr}; @@ -63,7 +62,7 @@ pub unsafe fn main() -> ! { mem::virtual_memory::kvminit(); mem::virtual_memory::kvminithart(); proc::process::procinit(); - trap::trapinithart(); + arch::trap::inithart(); arch::interrupt::init(); arch::interrupt::inithart(); io::bio::binit(); @@ -77,7 +76,7 @@ pub unsafe fn main() -> ! { core::hint::spin_loop(); } mem::virtual_memory::kvminithart(); - trap::trapinithart(); + arch::trap::inithart(); arch::interrupt::inithart(); } diff --git a/kernel/rustkernel/src/mem/virtual_memory.rs b/kernel/rustkernel/src/mem/virtual_memory.rs index 4c5c4ad..2c641d8 100644 --- a/kernel/rustkernel/src/mem/virtual_memory.rs +++ b/kernel/rustkernel/src/mem/virtual_memory.rs @@ -4,14 +4,9 @@ use crate::{ hardware::{UART0, VIRTIO0}, mem::{ round_down_page, round_up_page, Pagetable, PagetableEntry, KERNEL_BASE, PAGE_SIZE, - PHYSICAL_END, TRAMPOLINE, VIRTUAL_MAX, PTE_R, PTE_U, PTE_V, PTE_W, PTE_X, - }, - riscv::{ - asm, make_satp, - plic::PLIC, - power::QEMU_POWER, - mem::pte2pa, + PHYSICAL_END, PTE_R, PTE_U, PTE_V, PTE_W, PTE_X, TRAMPOLINE, VIRTUAL_MAX, }, + riscv::{asm, make_satp, mem::pte2pa, plic::PLIC, power::QEMU_POWER}, }, mem::{ kalloc::{kalloc, kfree}, diff --git a/kernel/rustkernel/src/proc/process.rs b/kernel/rustkernel/src/proc/process.rs index 619ff80..ea137dc 100644 --- a/kernel/rustkernel/src/proc/process.rs +++ b/kernel/rustkernel/src/proc/process.rs @@ -8,8 +8,8 @@ use super::{ }; use crate::{ arch::{ - mem::{Pagetable, PAGE_SIZE, TRAMPOLINE, TRAPFRAME, - PTE_R, PTE_W, PTE_X}, + mem::{Pagetable, PAGE_SIZE, PTE_R, PTE_W, PTE_X, TRAMPOLINE, TRAPFRAME}, + trap::InterruptBlocker, }, fs::{ file::{fileclose, filedup, File, Inode}, @@ -135,7 +135,7 @@ impl Process { } } pub fn current() -> Option<&'static mut Process> { - let _ = crate::trap::InterruptBlocker::new(); + let _ = InterruptBlocker::new(); let p = Cpu::current().proc; if p.is_null() { None diff --git a/kernel/rustkernel/src/sync/lock.rs b/kernel/rustkernel/src/sync/lock.rs index c48876b..d78a235 100644 --- a/kernel/rustkernel/src/sync/lock.rs +++ b/kernel/rustkernel/src/sync/lock.rs @@ -30,7 +30,7 @@ impl Lock { match lock_strategy { LockStrategy::Spin => { - crate::trap::push_intr_off(); + crate::arch::trap::push_intr_off(); while self.locked.swap(true, Ordering::Acquire) { core::hint::spin_loop(); @@ -64,7 +64,7 @@ impl Lock { match lock_strategy { LockStrategy::Spin => { - crate::trap::pop_intr_off(); + crate::arch::trap::pop_intr_off(); } LockStrategy::Sleep => { wakeup(addr_of!(*self).cast_mut().cast()); diff --git a/kernel/rustkernel/src/sync/spinlock.rs b/kernel/rustkernel/src/sync/spinlock.rs index d6ea3bc..1c8a316 100644 --- a/kernel/rustkernel/src/sync/spinlock.rs +++ b/kernel/rustkernel/src/sync/spinlock.rs @@ -1,9 +1,9 @@ use crate::{ + arch::trap::{pop_intr_off, push_intr_off}, proc::{ process::{Process, ProcessState}, scheduler::sched, }, - trap::{pop_intr_off, push_intr_off}, }; use core::{ ffi::c_char, diff --git a/kernel/rustkernel/src/syscall.rs b/kernel/rustkernel/src/syscall.rs index ecae1de..719a7dc 100644 --- a/kernel/rustkernel/src/syscall.rs +++ b/kernel/rustkernel/src/syscall.rs @@ -1,5 +1,5 @@ use crate::{ - arch::power::shutdown, + arch::{clock::CLOCK_TICKS, power::shutdown}, fs::{ self, file::{self, File}, @@ -10,7 +10,6 @@ use crate::{ println, proc::process::Process, string::strlen, - trap::CLOCK_TICKS, NOFILE, }; use core::{