We should disable sie before trapping back to user.

This commit is contained in:
Yifan Wu 2022-03-10 16:27:05 -08:00
parent fbe8e39b38
commit 334d868a5c
8 changed files with 43 additions and 33 deletions

View File

@ -28,31 +28,18 @@ pub fn device_init() {
plic.enable(hart_id, supervisor, intr_src_id);
plic.set_priority(intr_src_id, 1);
}
crate::println!(
"Hart0M threshold = {}",
plic.get_threshold(hart_id, IntrTargetPriority::Machine)
);
crate::println!(
"Hart0S threshold = {}",
plic.get_threshold(hart_id, IntrTargetPriority::Supervisor)
);
crate::println!("1 prio = {}", plic.get_priority(1));
crate::println!("10 prio = {}", plic.get_priority(10));
unsafe {
sie::set_sext();
}
}
pub fn irq_handler() {
//crate::println!("->irq_handler");
let mut plic = unsafe { PLIC::new(VIRT_PLIC) };
let intr_src_id = plic.claim(0, IntrTargetPriority::Supervisor);
//crate::println!("intr_src={}", intr_src_id);
match intr_src_id {
1 => BLOCK_DEVICE.handle_irq(),
10 => UART.handle_irq(),
_ => panic!("unsupported IRQ {}", intr_src_id),
}
plic.complete(0, IntrTargetPriority::Supervisor, intr_src_id);
//crate::println!("irq_handler->");
}

View File

@ -7,8 +7,8 @@ struct Stdout;
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
for c in s.chars() {
//UART.write(c as u8);
console_putchar(c as usize);
UART.write(c as u8);
//console_putchar(c as usize);
}
Ok(())
}

View File

@ -28,10 +28,17 @@ impl BlockDevice for VirtIOBlock {
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
if nb {
let mut resp = BlkResp::default();
/*
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
let token = unsafe { blk.read_block_nb(block_id, buf, &mut resp).unwrap() };
self.condvars.get(&token).unwrap().wait_no_sched()
});
*/
let mut blk = self.virtio_blk.exclusive_access();
let token = unsafe { blk.read_block_nb(block_id, buf, &mut resp).unwrap() };
//println!("waiting on token {}", token);
let task_cx_ptr = self.condvars.get(&token).unwrap().wait_no_sched();
drop(blk);
schedule(task_cx_ptr);
assert_eq!(
resp.status(),
@ -49,10 +56,16 @@ impl BlockDevice for VirtIOBlock {
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
if nb {
let mut resp = BlkResp::default();
/*
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
let token = unsafe { blk.write_block_nb(block_id, buf, &mut resp).unwrap() };
self.condvars.get(&token).unwrap().wait_no_sched()
});
*/
let mut blk = self.virtio_blk.exclusive_access();
let token = unsafe { blk.write_block_nb(block_id, buf, &mut resp).unwrap() };
let task_cx_ptr = self.condvars.get(&token).unwrap().wait_no_sched();
drop(blk);
schedule(task_cx_ptr);
assert_eq!(
resp.status(),
@ -68,6 +81,7 @@ impl BlockDevice for VirtIOBlock {
}
fn handle_irq(&self) {
//println!("into handle_irq");
/*
self.virtio_blk.exclusive_session(|blk| {
//println!("not panic here");
while let Ok(token) = blk.pop_used() {
@ -75,6 +89,12 @@ impl BlockDevice for VirtIOBlock {
self.condvars.get(&token).unwrap().signal();
}
});
*/
let mut blk = self.virtio_blk.exclusive_access();
while let Ok(token) = blk.pop_used() {
//println!("wakeup virtio.token {}", token);
self.condvars.get(&token).unwrap().signal();
}
}
}

View File

@ -146,15 +146,15 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> {
impl<const BASE_ADDR: usize> CharDevice for NS16550a<BASE_ADDR> {
fn read(&self) -> u8 {
println!("NS16550a::read");
//println!("NS16550a::read");
loop {
let mut inner = self.inner.exclusive_access();
if let Some(ch) = inner.read_buffer.pop_front() {
return ch;
} else {
println!("no ch yet!");
let task_cx_ptr = self.condvar.wait_no_sched();
drop(inner);
//println!("before scheduling");
schedule(task_cx_ptr);
}
}
@ -167,7 +167,7 @@ impl<const BASE_ADDR: usize> CharDevice for NS16550a<BASE_ADDR> {
let mut inner = self.inner.exclusive_access();
let mut count = 0;
while let Some(ch) = inner.ns16550a.read() {
println!("got {}", ch as char);
//println!("got {}", ch as char);
count += 1;
inner.read_buffer.push_back(ch);
}

View File

@ -14,7 +14,7 @@ impl File for Stdin {
}
fn read(&self, mut user_buf: UserBuffer) -> usize {
assert_eq!(user_buf.len(), 1);
println!("before UART.read() in Stdin::read()");
//println!("before UART.read() in Stdin::read()");
let ch = UART.read();
unsafe {
user_buf.buffers[0].as_mut_ptr().write_volatile(ch);

View File

@ -36,9 +36,14 @@ impl Condvar {
}
pub fn wait_no_sched(&self) -> *mut TaskContext {
/*
self.inner.exclusive_session(|inner| {
inner.wait_queue.push_back(current_task().unwrap());
});
*/
let mut inner = self.inner.exclusive_access();
inner.wait_queue.push_back(current_task().unwrap());
drop(inner);
block_current_task()
}

View File

@ -3,6 +3,7 @@ use core::ops::{Deref, DerefMut};
use riscv::register::sstatus;
use lazy_static::*;
/*
/// Wrap a static data structure inside it so that we are
/// able to access it without any `unsafe`.
///
@ -30,6 +31,7 @@ impl<T> UPSafeCell<T> {
self.inner.borrow_mut()
}
}
*/
pub struct UPSafeCellRaw<T> {
inner: UnsafeCell<T>,
@ -105,10 +107,12 @@ impl<T> UPIntrFreeCell<T> {
UPIntrRefMut(Some(self.inner.borrow_mut()))
}
/*
pub fn exclusive_session<F, V>(&self, f: F) -> V where F: FnOnce(&mut T) -> V {
let mut inner = self.exclusive_access();
f(inner.deref_mut())
}
*/
}
impl<'a, T> Drop for UPIntrRefMut<'a, T> {

View File

@ -50,6 +50,12 @@ fn enable_supervisor_interrupt() {
}
}
fn disable_supervisor_interrupt() {
unsafe {
sstatus::clear_sie();
}
}
#[no_mangle]
pub fn trap_handler() -> ! {
set_kernel_trap_entry();
@ -62,8 +68,6 @@ pub fn trap_handler() -> ! {
let mut cx = current_trap_cx();
cx.sepc += 4;
//println!("syscall id={}", cx.x[17]);
//println!("after setting sstatus.sie");
enable_supervisor_interrupt();
// get system call return value
@ -117,6 +121,7 @@ pub fn trap_handler() -> ! {
#[no_mangle]
pub fn trap_return() -> ! {
disable_supervisor_interrupt();
set_user_trap_entry();
let trap_cx_user_va = current_trap_cx_user_va();
let user_satp = current_user_token();
@ -139,17 +144,7 @@ pub fn trap_return() -> ! {
}
#[no_mangle]
pub fn trap_from_kernel(trap_cx: &TrapContext) {
/*
use riscv::register::sepc;
println!("a trap {:?} from kernel!", scause::read().cause());
println!("stval = {:#x}, sepc = {:#x}", stval::read(), sepc::read());
//panic!("a trap {:?} from kernel!", scause::read().cause());
*/
//panic!("a trap {:?} from kernel!", scause::read().cause());
//println!("->trap_from_kernel");
//println!("a trap {:?} from kernel!", scause::read().cause());
//println!("sepc = {:#x}", trap_cx.sepc);
pub fn trap_from_kernel(_trap_cx: &TrapContext) {
let scause = scause::read();
let stval = stval::read();
match scause.cause() {
@ -169,7 +164,6 @@ pub fn trap_from_kernel(trap_cx: &TrapContext) {
);
},
}
//println!("trap_from_kernel->");
}
pub use context::TrapContext;