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

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