feature: add derive macro for auto-CharDevice

This commit is contained in:
Mark Poliakov 2021-11-11 21:15:12 +02:00
parent 41ffd0ddb7
commit 47ef7e29fe
8 changed files with 98 additions and 49 deletions

17
Cargo.lock generated
View File

@ -73,6 +73,7 @@ dependencies = [
"cortex-a",
"fdt-rs",
"libsys",
"macros",
"memfs",
"tock-registers",
"vfs",
@ -92,6 +93,14 @@ dependencies = [
"libsys",
]
[[package]]
name = "macros"
version = "0.1.0"
dependencies = [
"quote",
"syn",
]
[[package]]
name = "memfs"
version = "0.1.0"
@ -135,9 +144,9 @@ version = "0.1.0"
[[package]]
name = "proc-macro2"
version = "1.0.29"
version = "1.0.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43"
dependencies = [
"unicode-xid",
]
@ -183,9 +192,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "syn"
version = "1.0.80"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194"
checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966"
dependencies = [
"proc-macro2",
"quote",

View File

@ -9,11 +9,12 @@ edition = "2018"
[workspace]
members = [
"fs/vfs",
"fs/memfs",
"fs/fat32",
"libsys",
"fs/memfs",
"fs/vfs",
"kernel",
"kernel/macros",
"libsys",
"libusr",
"user",
]

View File

@ -17,6 +17,7 @@ cfg-if = "1.x.x"
tock-registers = "0.7.x"
fdt-rs = { version = "0.x.x", default-features = false }
bitflags = "^1.3.0"
macros = { path = "macros" }
[target.'cfg(target_arch = "aarch64")'.dependencies]
cortex-a = { version = "6.x.x" }

13
kernel/macros/Cargo.toml Normal file
View File

@ -0,0 +1,13 @@
[package]
name = "macros"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
proc-macro = true
[dependencies]
syn = "^1.0.81"
quote = "^1.0.10"

38
kernel/macros/src/lib.rs Normal file
View File

@ -0,0 +1,38 @@
extern crate proc_macro;
extern crate syn;
#[macro_use]
extern crate quote;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
#[proc_macro_derive(TtyCharDevice)]
pub fn derive_tty_char_device(input: TokenStream) -> TokenStream {
let ast = parse_macro_input!(input as DeriveInput);
if !ast.generics.params.is_empty() {
panic!(
"Derived TtyCharDevice cannot have generic parameters: {:?}",
ast.ident
);
}
let ident = ast.ident;
quote! {
impl vfs::CharDevice for #ident {
fn read(&self, blocking: bool, data: &mut [u8]) -> Result<usize, libsys::error::Errno> {
assert!(blocking);
crate::dev::tty::TtyDevice::line_read(self, data)
}
fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, libsys::error::Errno> {
assert!(blocking);
crate::dev::tty::TtyDevice::line_write(self, data)
}
fn ioctl(&self, cmd: libsys::ioctl::IoctlCmd, ptr: usize, len: usize) ->
Result<usize, libsys::error::Errno>
{
crate::dev::tty::TtyDevice::tty_ioctl(self, cmd, ptr, len)
}
}
}.into()
}

View File

@ -12,7 +12,6 @@ use libsys::error::Errno;
use tock_registers::interfaces::{ReadWriteable, Readable, Writeable};
use tock_registers::registers::{Aliased, ReadOnly, ReadWrite};
use tock_registers::{register_bitfields, register_structs};
use vfs::{CharDevice, IoctlCmd};
register_bitfields! [
u32,
@ -78,6 +77,7 @@ struct UartInner {
regs: DeviceMemoryIo<Regs>,
}
#[derive(TtyCharDevice)]
pub(super) struct Uart {
inner: InitOnce<IrqSafeSpinLock<UartInner>>,
ring: CharRing<16>,
@ -123,22 +123,6 @@ impl SerialDevice for Uart {
}
}
impl CharDevice for Uart {
fn read(&self, blocking: bool, data: &mut [u8]) -> Result<usize, Errno> {
assert!(blocking);
self.line_read(data)
}
fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, Errno> {
assert!(blocking);
self.line_write(data)
}
fn ioctl(&self, cmd: IoctlCmd, ptr: usize, len: usize) -> Result<usize, Errno> {
self.tty_ioctl(cmd, ptr, len)
}
}
impl TtyDevice<16> for Uart {
fn ring(&self) -> &CharRing<16> {
&self.ring

View File

@ -78,6 +78,7 @@ struct Pl011Inner {
}
/// Device struct for PL011
#[derive(TtyCharDevice)]
pub struct Pl011 {
inner: InitOnce<IrqSafeSpinLock<Pl011Inner>>,
ring: CharRing<16>,
@ -117,16 +118,16 @@ impl Pl011Inner {
}
}
impl fmt::Write for Pl011Inner {
fn write_str(&mut self, s: &str) -> fmt::Result {
for &c in s.as_bytes() {
unsafe {
self.send(c);
}
}
Ok(())
}
}
// impl fmt::Write for Pl011Inner {
// fn write_str(&mut self, s: &str) -> fmt::Result {
// for &c in s.as_bytes() {
// unsafe {
// self.send(c);
// }
// }
// Ok(())
// }
// }
impl IntSource for Pl011 {
fn handle_irq(&self) -> Result<(), Errno> {
@ -168,21 +169,21 @@ impl SerialDevice for Pl011 {
}
}
impl CharDevice for Pl011 {
fn read(&self, blocking: bool, data: &mut [u8]) -> Result<usize, Errno> {
assert!(blocking);
self.line_read(data)
}
fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, Errno> {
assert!(blocking);
self.line_write(data)
}
fn ioctl(&self, cmd: IoctlCmd, ptr: usize, len: usize) -> Result<usize, Errno> {
self.tty_ioctl(cmd, ptr, len)
}
}
// impl CharDevice for Pl011 {
// fn read(&self, blocking: bool, data: &mut [u8]) -> Result<usize, Errno> {
// assert!(blocking);
// self.line_read(data)
// }
//
// fn write(&self, blocking: bool, data: &[u8]) -> Result<usize, Errno> {
// assert!(blocking);
// self.line_write(data)
// }
//
// fn ioctl(&self, cmd: IoctlCmd, ptr: usize, len: usize) -> Result<usize, Errno> {
// self.tty_ioctl(cmd, ptr, len)
// }
// }
impl TtyDevice<16> for Pl011 {
fn ring(&self) -> &CharRing<16> {

View File

@ -18,6 +18,8 @@
#![no_main]
#![warn(missing_docs)]
#[macro_use]
extern crate macros;
#[macro_use]
extern crate cfg_if;
#[macro_use]