mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 09:26:26 +04:00
We should disable sie before trapping back to user.
This commit is contained in:
parent
fbe8e39b38
commit
334d868a5c
@ -28,31 +28,18 @@ pub fn device_init() {
|
|||||||
plic.enable(hart_id, supervisor, intr_src_id);
|
plic.enable(hart_id, supervisor, intr_src_id);
|
||||||
plic.set_priority(intr_src_id, 1);
|
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 {
|
unsafe {
|
||||||
sie::set_sext();
|
sie::set_sext();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn irq_handler() {
|
pub fn irq_handler() {
|
||||||
//crate::println!("->irq_handler");
|
|
||||||
let mut plic = unsafe { PLIC::new(VIRT_PLIC) };
|
let mut plic = unsafe { PLIC::new(VIRT_PLIC) };
|
||||||
let intr_src_id = plic.claim(0, IntrTargetPriority::Supervisor);
|
let intr_src_id = plic.claim(0, IntrTargetPriority::Supervisor);
|
||||||
//crate::println!("intr_src={}", intr_src_id);
|
|
||||||
match intr_src_id {
|
match intr_src_id {
|
||||||
1 => BLOCK_DEVICE.handle_irq(),
|
1 => BLOCK_DEVICE.handle_irq(),
|
||||||
10 => UART.handle_irq(),
|
10 => UART.handle_irq(),
|
||||||
_ => panic!("unsupported IRQ {}", intr_src_id),
|
_ => panic!("unsupported IRQ {}", intr_src_id),
|
||||||
}
|
}
|
||||||
plic.complete(0, IntrTargetPriority::Supervisor, intr_src_id);
|
plic.complete(0, IntrTargetPriority::Supervisor, intr_src_id);
|
||||||
//crate::println!("irq_handler->");
|
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,8 @@ struct Stdout;
|
|||||||
impl Write for Stdout {
|
impl Write for Stdout {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
for c in s.chars() {
|
for c in s.chars() {
|
||||||
//UART.write(c as u8);
|
UART.write(c as u8);
|
||||||
console_putchar(c as usize);
|
//console_putchar(c as usize);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,17 @@ impl BlockDevice for VirtIOBlock {
|
|||||||
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
|
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
|
||||||
if nb {
|
if nb {
|
||||||
let mut resp = BlkResp::default();
|
let mut resp = BlkResp::default();
|
||||||
|
/*
|
||||||
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
|
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
|
||||||
let token = unsafe { blk.read_block_nb(block_id, buf, &mut resp).unwrap() };
|
let token = unsafe { blk.read_block_nb(block_id, buf, &mut resp).unwrap() };
|
||||||
self.condvars.get(&token).unwrap().wait_no_sched()
|
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);
|
schedule(task_cx_ptr);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.status(),
|
resp.status(),
|
||||||
@ -49,10 +56,16 @@ impl BlockDevice for VirtIOBlock {
|
|||||||
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
|
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
|
||||||
if nb {
|
if nb {
|
||||||
let mut resp = BlkResp::default();
|
let mut resp = BlkResp::default();
|
||||||
|
/*
|
||||||
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
|
let task_cx_ptr = self.virtio_blk.exclusive_session(|blk| {
|
||||||
let token = unsafe { blk.write_block_nb(block_id, buf, &mut resp).unwrap() };
|
let token = unsafe { blk.write_block_nb(block_id, buf, &mut resp).unwrap() };
|
||||||
self.condvars.get(&token).unwrap().wait_no_sched()
|
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);
|
schedule(task_cx_ptr);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
resp.status(),
|
resp.status(),
|
||||||
@ -68,6 +81,7 @@ impl BlockDevice for VirtIOBlock {
|
|||||||
}
|
}
|
||||||
fn handle_irq(&self) {
|
fn handle_irq(&self) {
|
||||||
//println!("into handle_irq");
|
//println!("into handle_irq");
|
||||||
|
/*
|
||||||
self.virtio_blk.exclusive_session(|blk| {
|
self.virtio_blk.exclusive_session(|blk| {
|
||||||
//println!("not panic here");
|
//println!("not panic here");
|
||||||
while let Ok(token) = blk.pop_used() {
|
while let Ok(token) = blk.pop_used() {
|
||||||
@ -75,6 +89,12 @@ impl BlockDevice for VirtIOBlock {
|
|||||||
self.condvars.get(&token).unwrap().signal();
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,15 +146,15 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> {
|
|||||||
|
|
||||||
impl<const BASE_ADDR: usize> CharDevice for NS16550a<BASE_ADDR> {
|
impl<const BASE_ADDR: usize> CharDevice for NS16550a<BASE_ADDR> {
|
||||||
fn read(&self) -> u8 {
|
fn read(&self) -> u8 {
|
||||||
println!("NS16550a::read");
|
//println!("NS16550a::read");
|
||||||
loop {
|
loop {
|
||||||
let mut inner = self.inner.exclusive_access();
|
let mut inner = self.inner.exclusive_access();
|
||||||
if let Some(ch) = inner.read_buffer.pop_front() {
|
if let Some(ch) = inner.read_buffer.pop_front() {
|
||||||
return ch;
|
return ch;
|
||||||
} else {
|
} else {
|
||||||
println!("no ch yet!");
|
|
||||||
let task_cx_ptr = self.condvar.wait_no_sched();
|
let task_cx_ptr = self.condvar.wait_no_sched();
|
||||||
drop(inner);
|
drop(inner);
|
||||||
|
//println!("before scheduling");
|
||||||
schedule(task_cx_ptr);
|
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 inner = self.inner.exclusive_access();
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
while let Some(ch) = inner.ns16550a.read() {
|
while let Some(ch) = inner.ns16550a.read() {
|
||||||
println!("got {}", ch as char);
|
//println!("got {}", ch as char);
|
||||||
count += 1;
|
count += 1;
|
||||||
inner.read_buffer.push_back(ch);
|
inner.read_buffer.push_back(ch);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ impl File for Stdin {
|
|||||||
}
|
}
|
||||||
fn read(&self, mut user_buf: UserBuffer) -> usize {
|
fn read(&self, mut user_buf: UserBuffer) -> usize {
|
||||||
assert_eq!(user_buf.len(), 1);
|
assert_eq!(user_buf.len(), 1);
|
||||||
println!("before UART.read() in Stdin::read()");
|
//println!("before UART.read() in Stdin::read()");
|
||||||
let ch = UART.read();
|
let ch = UART.read();
|
||||||
unsafe {
|
unsafe {
|
||||||
user_buf.buffers[0].as_mut_ptr().write_volatile(ch);
|
user_buf.buffers[0].as_mut_ptr().write_volatile(ch);
|
||||||
|
@ -36,9 +36,14 @@ impl Condvar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_no_sched(&self) -> *mut TaskContext {
|
pub fn wait_no_sched(&self) -> *mut TaskContext {
|
||||||
|
/*
|
||||||
self.inner.exclusive_session(|inner| {
|
self.inner.exclusive_session(|inner| {
|
||||||
inner.wait_queue.push_back(current_task().unwrap());
|
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()
|
block_current_task()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ use core::ops::{Deref, DerefMut};
|
|||||||
use riscv::register::sstatus;
|
use riscv::register::sstatus;
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
|
|
||||||
|
/*
|
||||||
/// Wrap a static data structure inside it so that we are
|
/// Wrap a static data structure inside it so that we are
|
||||||
/// able to access it without any `unsafe`.
|
/// able to access it without any `unsafe`.
|
||||||
///
|
///
|
||||||
@ -30,6 +31,7 @@ impl<T> UPSafeCell<T> {
|
|||||||
self.inner.borrow_mut()
|
self.inner.borrow_mut()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub struct UPSafeCellRaw<T> {
|
pub struct UPSafeCellRaw<T> {
|
||||||
inner: UnsafeCell<T>,
|
inner: UnsafeCell<T>,
|
||||||
@ -105,10 +107,12 @@ impl<T> UPIntrFreeCell<T> {
|
|||||||
UPIntrRefMut(Some(self.inner.borrow_mut()))
|
UPIntrRefMut(Some(self.inner.borrow_mut()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn exclusive_session<F, V>(&self, f: F) -> V where F: FnOnce(&mut T) -> V {
|
pub fn exclusive_session<F, V>(&self, f: F) -> V where F: FnOnce(&mut T) -> V {
|
||||||
let mut inner = self.exclusive_access();
|
let mut inner = self.exclusive_access();
|
||||||
f(inner.deref_mut())
|
f(inner.deref_mut())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Drop for UPIntrRefMut<'a, T> {
|
impl<'a, T> Drop for UPIntrRefMut<'a, T> {
|
||||||
|
@ -50,6 +50,12 @@ fn enable_supervisor_interrupt() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn disable_supervisor_interrupt() {
|
||||||
|
unsafe {
|
||||||
|
sstatus::clear_sie();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_handler() -> ! {
|
pub fn trap_handler() -> ! {
|
||||||
set_kernel_trap_entry();
|
set_kernel_trap_entry();
|
||||||
@ -62,8 +68,6 @@ pub fn trap_handler() -> ! {
|
|||||||
let mut cx = current_trap_cx();
|
let mut cx = current_trap_cx();
|
||||||
cx.sepc += 4;
|
cx.sepc += 4;
|
||||||
|
|
||||||
//println!("syscall id={}", cx.x[17]);
|
|
||||||
//println!("after setting sstatus.sie");
|
|
||||||
enable_supervisor_interrupt();
|
enable_supervisor_interrupt();
|
||||||
|
|
||||||
// get system call return value
|
// get system call return value
|
||||||
@ -117,6 +121,7 @@ pub fn trap_handler() -> ! {
|
|||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_return() -> ! {
|
pub fn trap_return() -> ! {
|
||||||
|
disable_supervisor_interrupt();
|
||||||
set_user_trap_entry();
|
set_user_trap_entry();
|
||||||
let trap_cx_user_va = current_trap_cx_user_va();
|
let trap_cx_user_va = current_trap_cx_user_va();
|
||||||
let user_satp = current_user_token();
|
let user_satp = current_user_token();
|
||||||
@ -139,17 +144,7 @@ pub fn trap_return() -> ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub fn trap_from_kernel(trap_cx: &TrapContext) {
|
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);
|
|
||||||
let scause = scause::read();
|
let scause = scause::read();
|
||||||
let stval = stval::read();
|
let stval = stval::read();
|
||||||
match scause.cause() {
|
match scause.cause() {
|
||||||
@ -169,7 +164,6 @@ pub fn trap_from_kernel(trap_cx: &TrapContext) {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
//println!("trap_from_kernel->");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use context::TrapContext;
|
pub use context::TrapContext;
|
||||||
|
Loading…
Reference in New Issue
Block a user