arch trap

This commit is contained in:
Garen Tyler 2023-11-09 20:48:10 -07:00
parent cbea3a19f4
commit 8edb4c2427
Signed by: garentyler
GPG Key ID: D7A048C454CB7054
15 changed files with 153 additions and 146 deletions

View File

@ -1,4 +0,0 @@
//! Architecture-agnostic CPU functions.
#[cfg(target_arch = "riscv64")]
pub use super::riscv::cpu::cpu_id;

View File

@ -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,
},
};

View File

@ -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)
}

View File

@ -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;
}

View File

@ -1,4 +0,0 @@
//! Architecture-agnostic power handling.
#[cfg(target_arch = "riscv64")]
pub use super::riscv::power::shutdown;

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}

View File

@ -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},

View File

@ -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

View File

@ -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());

View File

@ -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,

View File

@ -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::{