Skip to content

Commit e0f842c

Browse files
committed
refactor: uart16550 驱动拆分到单独的库中
Signed-off-by: YdrMaster <[email protected]>
1 parent 736273e commit e0f842c

File tree

5 files changed

+31
-67
lines changed

5 files changed

+31
-67
lines changed

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rustsbi-qemu/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ rcore-console = "0.0.0"
2727
aclint = "0.0.0"
2828
sifive-test-device = "0.0.0"
2929
dtb-walker = "=0.2.0-alpha.3"
30+
uart16550 = { git = "https://github.com/YdrMaster/uart16550", rev = "68ad4d8" }
3031

3132
hsm-cell = { path = "../hsm-cell" }
3233
fast-trap = { version = "=0.0.1", features = ["riscv-m"] }

rustsbi-qemu/src/dbcn.rs

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,8 @@ impl Console for DBCN {
2222
let start = bytes.phys_addr_lo();
2323
let end = start + bytes.num_bytes();
2424
if self.0.contains(&start) && self.0.contains(&(end - 1)) {
25-
let uart = uart16550::UART.lock();
26-
for ptr in start..end {
27-
let c = unsafe { (ptr as *const u8).read_volatile() };
28-
if !uart.get().write(c) {
29-
return SbiRet::success(ptr - start);
30-
}
31-
}
32-
SbiRet::success(bytes.num_bytes())
25+
let buf = unsafe { core::slice::from_raw_parts(start as *const u8, bytes.num_bytes()) };
26+
SbiRet::success(uart16550::UART.lock().get().write(buf))
3327
} else {
3428
SbiRet::invalid_param()
3529
}
@@ -39,15 +33,9 @@ impl Console for DBCN {
3933
let start = bytes.phys_addr_lo();
4034
let end = start + bytes.num_bytes();
4135
if self.0.contains(&start) && self.0.contains(&(end - 1)) {
42-
let uart = uart16550::UART.lock();
43-
for ptr in start..end {
44-
if let Some(c) = uart.get().read() {
45-
unsafe { (ptr as *mut u8).write_volatile(c) };
46-
} else {
47-
return SbiRet::success(ptr - start);
48-
}
49-
}
50-
SbiRet::success(bytes.num_bytes())
36+
let buf =
37+
unsafe { core::slice::from_raw_parts_mut(start as *mut u8, bytes.num_bytes()) };
38+
SbiRet::success(uart16550::UART.lock().get().read(buf))
5139
} else {
5240
SbiRet::invalid_param()
5341
}
@@ -57,7 +45,7 @@ impl Console for DBCN {
5745
fn write_byte(&self, byte: u8) -> SbiRet {
5846
let uart = uart16550::UART.lock();
5947
loop {
60-
if uart.get().write(byte) {
48+
if uart.get().write(&[byte]) == 1 {
6149
return SbiRet::success(0);
6250
}
6351
}

rustsbi-qemu/src/main.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,14 +262,17 @@ extern "C" fn fast_handler(
262262
ret.error = 0;
263263
ret.value = a1;
264264
}
265-
legacy::LEGACY_CONSOLE_GETCHAR => loop {
265+
legacy::LEGACY_CONSOLE_GETCHAR => {
266+
let mut c = 0u8;
266267
let uart = uart16550::UART.lock();
267-
if let Some(c) = uart.get().read() {
268-
ret.error = c as _;
269-
ret.value = a1;
270-
break;
268+
loop {
269+
if uart.get().read(core::slice::from_mut(&mut c)) == 1 {
270+
ret.error = c as _;
271+
ret.value = a1;
272+
break;
273+
}
271274
}
272-
},
275+
}
273276
_ => {}
274277
}
275278
}
@@ -325,18 +328,18 @@ impl rcore_console::Console for Console {
325328
#[inline]
326329
fn put_char(&self, c: u8) {
327330
let uart = uart16550::UART.lock();
328-
while !uart.get().write(c) {
331+
while uart.get().write(&[c]) == 0 {
329332
core::hint::spin_loop();
330333
}
331334
}
332335

333336
#[inline]
334337
fn put_str(&self, s: &str) {
335338
let uart = uart16550::UART.lock();
336-
for c in s.bytes() {
337-
while !uart.get().write(c) {
338-
core::hint::spin_loop();
339-
}
339+
let mut bytes = s.as_bytes();
340+
while !bytes.is_empty() {
341+
let count = uart.get().write(bytes);
342+
bytes = &bytes[count..];
340343
}
341344
}
342345
}

rustsbi-qemu/src/uart16550.rs

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,21 @@
1-
use core::{cell::UnsafeCell, ptr::null};
1+
use core::ptr::null;
22
use spin::lock_api::Mutex;
3+
use uart16550::Uart16550;
34

45
pub(crate) static UART: Mutex<Uart16550Map> = Mutex::new(Uart16550Map(null()));
56

67
pub(crate) fn init(base: usize) {
78
*UART.lock() = Uart16550Map(base as _);
89
}
910

10-
pub struct Uart16550Map(*const Uart16550);
11+
pub struct Uart16550Map(*const Uart16550<u8>);
1112

1213
unsafe impl Send for Uart16550Map {}
1314
unsafe impl Sync for Uart16550Map {}
1415

1516
impl Uart16550Map {
1617
#[inline]
17-
pub fn get(&self) -> &Uart16550 {
18+
pub fn get(&self) -> &Uart16550<u8> {
1819
unsafe { &*self.0 }
1920
}
2021
}
21-
22-
#[allow(unused)]
23-
pub struct Uart16550 {
24-
data: UnsafeCell<u8>,
25-
int_en: UnsafeCell<u8>,
26-
fifo_ctrl: UnsafeCell<u8>,
27-
line_ctrl: UnsafeCell<u8>,
28-
modem_ctrl: UnsafeCell<u8>,
29-
line_sts: UnsafeCell<u8>,
30-
}
31-
32-
impl Uart16550 {
33-
pub fn write(&self, data: u8) -> bool {
34-
const OUTPUT_EMPTY: u8 = 1 << 5;
35-
return unsafe {
36-
if self.line_sts.get().read_volatile() & OUTPUT_EMPTY == OUTPUT_EMPTY {
37-
self.data.get().write_volatile(data);
38-
true
39-
} else {
40-
false
41-
}
42-
};
43-
}
44-
45-
pub fn read(&self) -> Option<u8> {
46-
const INPUT_FULL: u8 = 1;
47-
return unsafe {
48-
if self.line_sts.get().read_volatile() & INPUT_FULL == INPUT_FULL {
49-
Some(self.data.get().read_volatile())
50-
} else {
51-
None
52-
}
53-
};
54-
}
55-
}

0 commit comments

Comments
 (0)