Still a lot of bugs :(

This commit is contained in:
Yifan Wu 2022-03-04 09:02:32 -08:00
parent 704eae3bb0
commit 26f44233f6
27 changed files with 308 additions and 95 deletions

View file

@ -3,7 +3,7 @@
#![allow(unused)]
use super::BlockDevice;
use crate::sync::UPSafeCell;
use crate::sync::UPIntrFreeCell;
use core::convert::TryInto;
use k210_hal::prelude::*;
use k210_pac::{Peripherals, SPI0};
@ -715,8 +715,8 @@ fn io_init() {
}
lazy_static! {
static ref PERIPHERALS: UPSafeCell<Peripherals> =
unsafe { UPSafeCell::new(Peripherals::take().unwrap()) };
static ref PERIPHERALS: UPIntrFreeCell<Peripherals> =
unsafe { UPIntrFreeCell::new(Peripherals::take().unwrap()) };
}
fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
@ -740,11 +740,11 @@ fn init_sdcard() -> SDCard<SPIImpl<SPI0>> {
sd
}
pub struct SDCardWrapper(UPSafeCell<SDCard<SPIImpl<SPI0>>>);
pub struct SDCardWrapper(UPIntrFreeCell<SDCard<SPIImpl<SPI0>>>);
impl SDCardWrapper {
pub fn new() -> Self {
unsafe { Self(UPSafeCell::new(init_sdcard())) }
unsafe { Self(UPIntrFreeCell::new(init_sdcard())) }
}
}

View file

@ -3,7 +3,8 @@ use crate::mm::{
frame_alloc, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum,
StepByOne, VirtAddr,
};
use crate::sync::{Condvar, UPSafeCell};
use crate::sync::{Condvar, UPIntrFreeCell};
use crate::task::schedule;
use crate::DEV_NON_BLOCKING_ACCESS;
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
@ -14,23 +15,24 @@ use virtio_drivers::{BlkResp, RespStatus, VirtIOBlk, VirtIOHeader};
const VIRTIO0: usize = 0x10001000;
pub struct VirtIOBlock {
virtio_blk: UPSafeCell<VirtIOBlk<'static>>,
virtio_blk: UPIntrFreeCell<VirtIOBlk<'static>>,
condvars: BTreeMap<u16, Condvar>,
}
lazy_static! {
static ref QUEUE_FRAMES: UPSafeCell<Vec<FrameTracker>> = unsafe { UPSafeCell::new(Vec::new()) };
static ref QUEUE_FRAMES: UPIntrFreeCell<Vec<FrameTracker>> = unsafe { UPIntrFreeCell::new(Vec::new()) };
}
impl BlockDevice for VirtIOBlock {
fn read_block(&self, block_id: usize, buf: &mut [u8]) {
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
if nb {
let mut blk = self.virtio_blk.exclusive_access();
let mut resp = BlkResp::default();
let token = unsafe { blk.read_block_nb(block_id, buf, &mut resp).unwrap() };
drop(blk);
self.condvars.get(&token).unwrap().wait();
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()
});
schedule(task_cx_ptr);
assert_eq!(
resp.status(),
RespStatus::Ok,
@ -46,11 +48,12 @@ impl BlockDevice for VirtIOBlock {
fn write_block(&self, block_id: usize, buf: &[u8]) {
let nb = *DEV_NON_BLOCKING_ACCESS.exclusive_access();
if nb {
let mut blk = self.virtio_blk.exclusive_access();
let mut resp = BlkResp::default();
let token = unsafe { blk.write_block_nb(block_id, buf, &mut resp).unwrap() };
drop(blk);
self.condvars.get(&token).unwrap().wait();
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()
});
schedule(task_cx_ptr);
assert_eq!(
resp.status(),
RespStatus::Ok,
@ -64,17 +67,21 @@ impl BlockDevice for VirtIOBlock {
}
}
fn handle_irq(&self) {
let mut blk = self.virtio_blk.exclusive_access();
while let Ok(token) = blk.pop_used() {
self.condvars.get(&token).unwrap().signal();
}
//println!("into handle_irq");
self.virtio_blk.exclusive_session(|blk| {
//println!("not panic here");
while let Ok(token) = blk.pop_used() {
//println!("wakeup virtio.token {}", token);
self.condvars.get(&token).unwrap().signal();
}
});
}
}
impl VirtIOBlock {
pub fn new() -> Self {
let virtio_blk = unsafe {
UPSafeCell::new(VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap())
UPIntrFreeCell::new(VirtIOBlk::new(&mut *(VIRTIO0 as *mut VirtIOHeader)).unwrap())
};
let mut condvars = BTreeMap::new();
let channels = virtio_blk.exclusive_access().virt_queue_size();

View file

@ -1,13 +1,14 @@
use super::CharDevice;
use crate::sync::{Condvar, UPSafeCell};
use alloc::collections::VecDeque;
use bitflags::*;
use volatile::{ReadOnly, Volatile, WriteOnly};
///! Ref: https://www.lammertbies.nl/comm/info/serial-uart
///! Ref: ns16550a datasheet: https://datasheetspdf.com/pdf-file/605590/NationalSemiconductor/NS16550A/1
///! Ref: ns16450 datasheet: https://datasheetspdf.com/pdf-file/1311818/NationalSemiconductor/NS16450/1
use super::CharDevice;
use crate::sync::{Condvar, UPIntrFreeCell};
use crate::task::schedule;
use alloc::collections::VecDeque;
use bitflags::*;
use volatile::{ReadOnly, Volatile, WriteOnly};
bitflags! {
/// InterruptEnableRegister
pub struct IER: u8 {
@ -125,7 +126,7 @@ struct NS16550aInner {
}
pub struct NS16550a<const BASE_ADDR: usize> {
inner: UPSafeCell<NS16550aInner>,
inner: UPIntrFreeCell<NS16550aInner>,
condvar: Condvar,
}
@ -137,7 +138,7 @@ impl<const BASE_ADDR: usize> NS16550a<BASE_ADDR> {
};
inner.ns16550a.init();
Self {
inner: unsafe { UPSafeCell::new(inner) },
inner: unsafe { UPIntrFreeCell::new(inner) },
condvar: Condvar::new(),
}
}
@ -145,13 +146,16 @@ 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");
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);
self.condvar.wait();
schedule(task_cx_ptr);
}
}
}
@ -163,10 +167,12 @@ 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);
count += 1;
inner.read_buffer.push_back(ch);
}
drop(inner);
//assert_eq!(count, 1);
if count > 0 {
self.condvar.signal();
}

View file

@ -1,3 +1,4 @@
#[allow(clippy::upper_case_acronyms)]
pub struct PLIC {
base_addr: usize,
}