Still a lot of bugs :(
This commit is contained in:
parent
704eae3bb0
commit
26f44233f6
27 changed files with 308 additions and 95 deletions
|
@ -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())) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#[allow(clippy::upper_case_acronyms)]
|
||||
pub struct PLIC {
|
||||
base_addr: usize,
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue