diff --git a/Cargo.lock b/Cargo.lock index e327a89bb..b57570fa9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -61,7 +61,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -184,10 +184,11 @@ version = "0.1.0" dependencies = [ "banscii-artist-interface-types", "banscii-assistant-core", - "banscii-pl011-driver-interface-types", + "embedded-hal-nb", "hex", "sel4-externally-shared", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", ] @@ -210,28 +211,13 @@ dependencies = [ ] [[package]] -name = "banscii-pl011-driver" +name = "banscii-serial-driver" version = "0.1.0" dependencies = [ - "banscii-pl011-driver-core", - "banscii-pl011-driver-interface-types", - "heapless", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", -] - -[[package]] -name = "banscii-pl011-driver-core" -version = "0.1.0" -dependencies = [ - "tock-registers", -] - -[[package]] -name = "banscii-pl011-driver-interface-types" -version = "0.1.0" -dependencies = [ - "serde", + "sel4-pl011-driver", ] [[package]] @@ -373,6 +359,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "num-traits", + "serde", +] + [[package]] name = "clang-sys" version = "1.7.0" @@ -611,12 +607,43 @@ dependencies = [ "void", ] +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + [[package]] name = "embedded-io" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + [[package]] name = "env_logger" version = "0.10.2" @@ -1082,25 +1109,9 @@ dependencies = [ name = "microkit-http-server-example-pl031-driver" version = "0.1.0" dependencies = [ - "microkit-http-server-example-pl031-driver-core", - "microkit-http-server-example-pl031-driver-interface-types", "sel4-microkit", - "sel4-microkit-message", -] - -[[package]] -name = "microkit-http-server-example-pl031-driver-core" -version = "0.1.0" -dependencies = [ - "log", - "tock-registers", -] - -[[package]] -name = "microkit-http-server-example-pl031-driver-interface-types" -version = "0.1.0" -dependencies = [ - "serde", + "sel4-microkit-driver-adapters", + "sel4-pl031-driver", ] [[package]] @@ -1109,13 +1120,11 @@ version = "0.1.0" dependencies = [ "async-unsync", "futures", + "lock_api", "log", - "microkit-http-server-example-pl031-driver-interface-types", "microkit-http-server-example-server-core", - "microkit-http-server-example-sp804-driver-interface-types", - "microkit-http-server-example-virtio-blk-driver-interface-types", - "microkit-http-server-example-virtio-net-driver-interface-types", "rcgen", + "rtcc", "sel4", "sel4-async-block-io", "sel4-async-block-io-fat", @@ -1123,10 +1132,12 @@ dependencies = [ "sel4-async-single-threaded-executor", "sel4-async-time", "sel4-bounce-buffer-allocator", + "sel4-driver-interfaces", "sel4-externally-shared", "sel4-immediate-sync-once-cell", "sel4-logging", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", "sel4-newlib", "sel4-shared-ring-buffer", @@ -1134,6 +1145,7 @@ dependencies = [ "sel4-shared-ring-buffer-block-io-types", "sel4-shared-ring-buffer-bookkeeping", "sel4-shared-ring-buffer-smoltcp", + "sel4-sync", "smoltcp", ] @@ -1141,6 +1153,7 @@ dependencies = [ name = "microkit-http-server-example-server-core" version = "0.1.0" dependencies = [ + "embedded-io-async", "futures", "httparse", "log", @@ -1164,25 +1177,11 @@ dependencies = [ name = "microkit-http-server-example-sp804-driver" version = "0.1.0" dependencies = [ - "microkit-http-server-example-sp804-driver-core", - "microkit-http-server-example-sp804-driver-interface-types", + "sel4-driver-interfaces", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", -] - -[[package]] -name = "microkit-http-server-example-sp804-driver-core" -version = "0.1.0" -dependencies = [ - "log", - "tock-registers", -] - -[[package]] -name = "microkit-http-server-example-sp804-driver-interface-types" -version = "0.1.0" -dependencies = [ - "serde", + "sel4-sp804-driver", ] [[package]] @@ -1190,36 +1189,19 @@ name = "microkit-http-server-example-virtio-blk-driver" version = "0.1.0" dependencies = [ "log", - "microkit-http-server-example-virtio-blk-driver-interface-types", - "microkit-http-server-example-virtio-hal-impl", "sel4", "sel4-bounce-buffer-allocator", + "sel4-driver-interfaces", "sel4-externally-shared", "sel4-immediate-sync-once-cell", "sel4-logging", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", "sel4-shared-ring-buffer", "sel4-shared-ring-buffer-block-io-types", - "virtio-drivers", -] - -[[package]] -name = "microkit-http-server-example-virtio-blk-driver-interface-types" -version = "0.1.0" -dependencies = [ - "serde", -] - -[[package]] -name = "microkit-http-server-example-virtio-hal-impl" -version = "0.1.0" -dependencies = [ - "log", - "sel4-bounce-buffer-allocator", - "sel4-externally-shared", - "sel4-immediate-sync-once-cell", - "sel4-sync", + "sel4-virtio-blk", + "sel4-virtio-hal-impl", "virtio-drivers", ] @@ -1228,26 +1210,20 @@ name = "microkit-http-server-example-virtio-net-driver" version = "0.1.0" dependencies = [ "log", - "microkit-http-server-example-virtio-hal-impl", - "microkit-http-server-example-virtio-net-driver-interface-types", "sel4", "sel4-bounce-buffer-allocator", "sel4-externally-shared", "sel4-immediate-sync-once-cell", "sel4-logging", "sel4-microkit", + "sel4-microkit-driver-adapters", "sel4-microkit-message", "sel4-shared-ring-buffer", + "sel4-virtio-hal-impl", + "sel4-virtio-net", "virtio-drivers", ] -[[package]] -name = "microkit-http-server-example-virtio-net-driver-interface-types" -version = "0.1.0" -dependencies = [ - "serde", -] - [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1583,7 +1559,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" dependencies = [ "cobs", - "embedded-io", + "embedded-io 0.4.0", "serde", ] @@ -1767,7 +1743,7 @@ checksum = "aa3145d2fae3778b1e31ec2e827b228bdc6abd9b74bb5705ba46dcb82069bc4f" dependencies = [ "bit_field", "critical-section", - "embedded-hal", + "embedded-hal 0.2.7", ] [[package]] @@ -1791,6 +1767,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rtcc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95973c3a0274adc4f3c5b70d2b5b85618d6de9559a6737d3293ecae9a2fc0839" +dependencies = [ + "chrono", +] + [[package]] name = "rustc-demangle" version = "0.1.23" @@ -1933,6 +1918,9 @@ dependencies = [ [[package]] name = "sel4-async-io" version = "0.1.0" +dependencies = [ + "embedded-io-async", +] [[package]] name = "sel4-async-network" @@ -1947,6 +1935,7 @@ dependencies = [ name = "sel4-async-network-rustls" version = "0.1.0" dependencies = [ + "embedded-io-async", "log", "rustls", "sel4-async-io", @@ -2059,6 +2048,15 @@ dependencies = [ "serde", ] +[[package]] +name = "sel4-bcm2835-aux-uart-driver" +version = "0.1.0" +dependencies = [ + "embedded-hal-nb", + "sel4-driver-interfaces", + "tock-registers", +] + [[package]] name = "sel4-bitfield-ops" version = "0.1.0" @@ -2264,6 +2262,17 @@ dependencies = [ "lock_api", ] +[[package]] +name = "sel4-driver-interfaces" +version = "0.1.0" +dependencies = [ + "embedded-hal-nb", + "heapless", + "lock_api", + "rtcc", + "serde", +] + [[package]] name = "sel4-elf-header" version = "0.1.0" @@ -2275,7 +2284,7 @@ dependencies = [ "cfg-if", "sel4-atomic-ptr", "volatile", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -2286,20 +2295,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "sel4-hal-adapters" -version = "0.1.0" -dependencies = [ - "log", - "sel4-bounce-buffer-allocator", - "sel4-externally-shared", - "sel4-microkit", - "sel4-microkit-message", - "sel4-shared-ring-buffer", - "serde", - "smoltcp", -] - [[package]] name = "sel4-immediate-sync-once-cell" version = "0.1.0" @@ -2322,6 +2317,7 @@ dependencies = [ "aarch64-cpu", "cc", "cfg-if", + "embedded-hal-nb", "glob", "heapless", "log", @@ -2330,6 +2326,7 @@ dependencies = [ "quote", "riscv", "sbi", + "sel4-bcm2835-aux-uart-driver", "sel4-build-env", "sel4-config", "sel4-immutable-cell", @@ -2338,12 +2335,12 @@ dependencies = [ "sel4-kernel-loader-embed-page-tables-runtime", "sel4-kernel-loader-payload-types", "sel4-logging", + "sel4-pl011-driver", "sel4-platform-info", "sel4-rustfmt-helper", "serde", "smccc", "spin 0.9.8", - "tock-registers", ] [[package]] @@ -2400,6 +2397,7 @@ dependencies = [ name = "sel4-logging" version = "0.1.0" dependencies = [ + "lock_api", "log", ] @@ -2427,6 +2425,25 @@ dependencies = [ "sel4-immutable-cell", ] +[[package]] +name = "sel4-microkit-driver-adapters" +version = "0.1.0" +dependencies = [ + "chrono", + "embedded-hal-nb", + "heapless", + "log", + "rtcc", + "sel4-bounce-buffer-allocator", + "sel4-driver-interfaces", + "sel4-externally-shared", + "sel4-microkit", + "sel4-microkit-message", + "sel4-shared-ring-buffer", + "serde", + "smoltcp", +] + [[package]] name = "sel4-microkit-macros" version = "0.1.0" @@ -2452,7 +2469,7 @@ dependencies = [ "num_enum", "postcard", "serde", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -2491,6 +2508,23 @@ dependencies = [ name = "sel4-panicking-env" version = "0.1.0" +[[package]] +name = "sel4-pl011-driver" +version = "0.1.0" +dependencies = [ + "embedded-hal-nb", + "sel4-driver-interfaces", + "tock-registers", +] + +[[package]] +name = "sel4-pl031-driver" +version = "0.1.0" +dependencies = [ + "rtcc", + "tock-registers", +] + [[package]] name = "sel4-platform-info" version = "0.1.0" @@ -2575,7 +2609,7 @@ version = "0.1.0" dependencies = [ "log", "sel4-externally-shared", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -2599,7 +2633,7 @@ version = "0.1.0" dependencies = [ "num_enum", "sel4-shared-ring-buffer", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -2674,7 +2708,7 @@ name = "sel4-simple-task-runtime-config-types" version = "0.1.0" dependencies = [ "serde", - "zerocopy 0.7.32", + "zerocopy", ] [[package]] @@ -2694,6 +2728,14 @@ dependencies = [ "sel4-panicking", ] +[[package]] +name = "sel4-sp804-driver" +version = "0.1.0" +dependencies = [ + "sel4-driver-interfaces", + "tock-registers", +] + [[package]] name = "sel4-sync" version = "0.1.0" @@ -2731,6 +2773,36 @@ dependencies = [ "sel4-panicking-env", ] +[[package]] +name = "sel4-virtio-blk" +version = "0.1.0" +dependencies = [ + "log", + "sel4-driver-interfaces", + "virtio-drivers", +] + +[[package]] +name = "sel4-virtio-hal-impl" +version = "0.1.0" +dependencies = [ + "sel4-bounce-buffer-allocator", + "sel4-externally-shared", + "sel4-immediate-sync-once-cell", + "sel4-sync", + "virtio-drivers", +] + +[[package]] +name = "sel4-virtio-net" +version = "0.1.0" +dependencies = [ + "log", + "sel4-driver-interfaces", + "smoltcp", + "virtio-drivers", +] + [[package]] name = "semver" version = "1.0.22" @@ -3273,13 +3345,13 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "virtio-drivers" -version = "0.5.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c1b8da1e59e77cdae29b32fb936614dc849352d7f58da199072067fe402bbcf" +checksum = "ff69e69ff755c004bb027891b58f951225832c84f6a734f9e1fdf0118aa91f91" dependencies = [ "bitflags 2.4.2", "log", - "zerocopy 0.6.6", + "zerocopy", ] [[package]] @@ -3524,16 +3596,6 @@ dependencies = [ "time", ] -[[package]] -name = "zerocopy" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854e949ac82d619ee9a14c66a1b674ac730422372ccb759ce0c39cabcf2bf8e6" -dependencies = [ - "byteorder", - "zerocopy-derive 0.6.6", -] - [[package]] name = "zerocopy" version = "0.7.32" @@ -3541,18 +3603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" dependencies = [ "byteorder", - "zerocopy-derive 0.7.32", -] - -[[package]] -name = "zerocopy-derive" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "125139de3f6b9d625c39e2efdd73d41bdac468ccd556556440e322be0e1bbd91" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.52", + "zerocopy-derive", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 243cd1519..b11ff850a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,28 +13,26 @@ default-members = [] resolver = "2" members = [ + "crates/drivers/bcm2835-aux-uart", + "crates/drivers/pl011", + "crates/drivers/pl031", + "crates/drivers/sp804", + "crates/drivers/virtio/blk", + "crates/drivers/virtio/hal-impl", + "crates/drivers/virtio/net", "crates/examples/microkit/banscii/pds/artist", "crates/examples/microkit/banscii/pds/artist/interface-types", "crates/examples/microkit/banscii/pds/assistant", "crates/examples/microkit/banscii/pds/assistant/core", "crates/examples/microkit/banscii/pds/assistant/core/test", - "crates/examples/microkit/banscii/pds/pl011-driver", - "crates/examples/microkit/banscii/pds/pl011-driver/core", - "crates/examples/microkit/banscii/pds/pl011-driver/interface-types", + "crates/examples/microkit/banscii/pds/serial-driver", "crates/examples/microkit/hello/pds/hello", - "crates/examples/microkit/http-server/helpers/virtio-hal-impl", "crates/examples/microkit/http-server/pds/pl031-driver", - "crates/examples/microkit/http-server/pds/pl031-driver/core", - "crates/examples/microkit/http-server/pds/pl031-driver/interface-types", "crates/examples/microkit/http-server/pds/server", "crates/examples/microkit/http-server/pds/server/core", "crates/examples/microkit/http-server/pds/sp804-driver", - "crates/examples/microkit/http-server/pds/sp804-driver/core", - "crates/examples/microkit/http-server/pds/sp804-driver/interface-types", "crates/examples/microkit/http-server/pds/virtio-blk-driver", - "crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types", "crates/examples/microkit/http-server/pds/virtio-net-driver", - "crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types", "crates/examples/root-task/example-root-task", "crates/examples/root-task/example-root-task-without-runtime", "crates/examples/root-task/hello", @@ -96,10 +94,10 @@ members = [ "crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec", "crates/sel4-capdl-initializer/with-embedded-spec/embedded-spec/validate", "crates/sel4-dlmalloc", + "crates/sel4-driver-interfaces", "crates/sel4-elf-header", "crates/sel4-externally-shared", "crates/sel4-generate-target-specs", - "crates/sel4-hal-adapters", "crates/sel4-immediate-sync-once-cell", "crates/sel4-immutable-cell", "crates/sel4-initialize-tls", @@ -112,6 +110,7 @@ members = [ "crates/sel4-logging", "crates/sel4-microkit", "crates/sel4-microkit/base", + "crates/sel4-microkit/driver-adapters", "crates/sel4-microkit/macros", "crates/sel4-microkit/message", "crates/sel4-microkit/message/types", diff --git a/crates/drivers/bcm2835-aux-uart/Cargo.nix b/crates/drivers/bcm2835-aux-uart/Cargo.nix new file mode 100644 index 000000000..af1fd4c80 --- /dev/null +++ b/crates/drivers/bcm2835-aux-uart/Cargo.nix @@ -0,0 +1,15 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates }: + +mk { + package.name = "sel4-bcm2835-aux-uart-driver"; + dependencies = { + inherit (versions) tock-registers embedded-hal-nb; + inherit (localCrates) sel4-driver-interfaces; + }; +} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.toml b/crates/drivers/bcm2835-aux-uart/Cargo.toml similarity index 74% rename from crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.toml rename to crates/drivers/bcm2835-aux-uart/Cargo.toml index bb1ee0c08..a9e5e6da4 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.toml +++ b/crates/drivers/bcm2835-aux-uart/Cargo.toml @@ -10,11 +10,13 @@ # [package] -name = "banscii-pl011-driver-interface-types" +name = "sel4-bcm2835-aux-uart-driver" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" [dependencies] -serde = { version = "1.0.147", default-features = false } +embedded-hal-nb = "1.0" +sel4-driver-interfaces = { path = "../../sel4-driver-interfaces" } +tock-registers = "0.8.1" diff --git a/crates/sel4-kernel-loader/src/drivers/bcm2835_aux_uart.rs b/crates/drivers/bcm2835-aux-uart/src/device.rs similarity index 68% rename from crates/sel4-kernel-loader/src/drivers/bcm2835_aux_uart.rs rename to crates/drivers/bcm2835-aux-uart/src/device.rs index 18a6a5eee..ad712bc68 100644 --- a/crates/sel4-kernel-loader/src/drivers/bcm2835_aux_uart.rs +++ b/crates/drivers/bcm2835-aux-uart/src/device.rs @@ -19,7 +19,7 @@ const MU_LSR_DATAREADY: u32 = 1 << 0; register_structs! { #[allow(non_snake_case)] - pub(crate)Bcm2835AuxUartRegisterBlock { + pub(crate) RegisterBlock { (0x000 => _reserved0), (0x040 => IO: ReadWrite), (0x041 => _reserved1), @@ -30,31 +30,31 @@ register_structs! { } } -pub(crate) struct Bcm2835AuxUartDevice { - base_addr: usize, +pub(crate) struct Device { + ptr: *mut RegisterBlock, } -impl Bcm2835AuxUartDevice { - pub(crate) const unsafe fn new(base_addr: usize) -> Self { - Self { base_addr } +impl Device { + pub(crate) const unsafe fn new(ptr: *mut RegisterBlock) -> Self { + Self { ptr } } - fn ptr(&self) -> *const Bcm2835AuxUartRegisterBlock { - self.base_addr as *const _ + fn ptr(&self) -> *const RegisterBlock { + self.ptr } pub(crate) fn init(&self) {} } -impl Deref for Bcm2835AuxUartDevice { - type Target = Bcm2835AuxUartRegisterBlock; +impl Deref for Device { + type Target = RegisterBlock; fn deref(&self) -> &Self::Target { unsafe { &*self.ptr() } } } -impl Bcm2835AuxUartDevice { +impl Device { pub(crate) fn put_char(&self, c: u8) { loop { if self.LSR.get() & MU_LSR_TXIDLE != 0 { diff --git a/crates/drivers/bcm2835-aux-uart/src/lib.rs b/crates/drivers/bcm2835-aux-uart/src/lib.rs new file mode 100644 index 000000000..fd0ff8b51 --- /dev/null +++ b/crates/drivers/bcm2835-aux-uart/src/lib.rs @@ -0,0 +1,74 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::convert::Infallible; + +use embedded_hal_nb::nb; +use embedded_hal_nb::serial; + +// use sel4_driver_interfaces::HandleInterrupt; + +mod device; + +use device::Device; + +pub struct Driver { + device: Device, +} + +unsafe impl Send for Driver {} +unsafe impl Sync for Driver {} + +impl Driver { + #[allow(clippy::missing_safety_doc)] + pub const unsafe fn new_uninit(ptr: *mut ()) -> Self { + Self { + device: Device::new(ptr.cast()), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(ptr: *mut ()) -> Self { + let mut this = Self::new_uninit(ptr); + this.init(); + this + } + + pub fn init(&mut self) { + self.device.init(); + } +} + +impl serial::ErrorType for Driver { + type Error = Infallible; +} + +// TODO +// impl serial::Read for Driver { +// fn read(&mut self) -> nb::Result { +// self.device.get_char().ok_or(nb::Error::WouldBlock) +// } +// } + +impl serial::Write for Driver { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + self.device.put_char(word); + Ok(()) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + Ok(()) + } +} + +// TODO +// impl HandleInterrupt for Driver { +// fn handle_interrupt(&mut self) { +// self.device.clear_all_interrupts() +// } +// } diff --git a/crates/drivers/pl011/Cargo.nix b/crates/drivers/pl011/Cargo.nix new file mode 100644 index 000000000..2b203a65c --- /dev/null +++ b/crates/drivers/pl011/Cargo.nix @@ -0,0 +1,15 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates }: + +mk { + package.name = "sel4-pl011-driver"; + dependencies = { + inherit (versions) tock-registers embedded-hal-nb; + inherit (localCrates) sel4-driver-interfaces; + }; +} diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.toml b/crates/drivers/pl011/Cargo.toml similarity index 80% rename from crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.toml rename to crates/drivers/pl011/Cargo.toml index 48f8563fe..804a06e2c 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.toml +++ b/crates/drivers/pl011/Cargo.toml @@ -10,12 +10,13 @@ # [package] -name = "microkit-http-server-example-sp804-driver-core" +name = "sel4-pl011-driver" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" [dependencies] -log = "0.4.17" +embedded-hal-nb = "1.0" +sel4-driver-interfaces = { path = "../../sel4-driver-interfaces" } tock-registers = "0.8.1" diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/core/src/device.rs b/crates/drivers/pl011/src/device.rs similarity index 93% rename from crates/examples/microkit/banscii/pds/pl011-driver/core/src/device.rs rename to crates/drivers/pl011/src/device.rs index 8a68a4d87..207ed729b 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/core/src/device.rs +++ b/crates/drivers/pl011/src/device.rs @@ -46,11 +46,11 @@ pub struct Device { } impl Device { - pub unsafe fn new(ptr: *mut RegisterBlock) -> Self { + pub const unsafe fn new(ptr: *mut RegisterBlock) -> Self { Self { ptr } } - fn ptr(&self) -> *mut RegisterBlock { + const fn ptr(&self) -> *mut RegisterBlock { self.ptr } diff --git a/crates/drivers/pl011/src/lib.rs b/crates/drivers/pl011/src/lib.rs new file mode 100644 index 000000000..8eabd12e5 --- /dev/null +++ b/crates/drivers/pl011/src/lib.rs @@ -0,0 +1,72 @@ +// +// Copyright 2023, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::convert::Infallible; + +use embedded_hal_nb::nb; +use embedded_hal_nb::serial; + +use sel4_driver_interfaces::HandleInterrupt; + +mod device; + +use device::Device; + +pub struct Driver { + device: Device, +} + +unsafe impl Send for Driver {} +unsafe impl Sync for Driver {} + +impl Driver { + #[allow(clippy::missing_safety_doc)] + pub const unsafe fn new_uninit(ptr: *mut ()) -> Self { + Self { + device: Device::new(ptr.cast()), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(ptr: *mut ()) -> Self { + let mut this = Self::new_uninit(ptr); + this.init(); + this + } + + pub fn init(&mut self) { + self.device.init(); + } +} + +impl serial::ErrorType for Driver { + type Error = Infallible; +} + +impl serial::Read for Driver { + fn read(&mut self) -> nb::Result { + self.device.get_char().ok_or(nb::Error::WouldBlock) + } +} + +impl serial::Write for Driver { + fn write(&mut self, word: u8) -> nb::Result<(), Self::Error> { + self.device.put_char(word); + Ok(()) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + Ok(()) + } +} + +impl HandleInterrupt for Driver { + fn handle_interrupt(&mut self) { + self.device.clear_all_interrupts() + } +} diff --git a/crates/drivers/pl031/Cargo.nix b/crates/drivers/pl031/Cargo.nix new file mode 100644 index 000000000..74965788a --- /dev/null +++ b/crates/drivers/pl031/Cargo.nix @@ -0,0 +1,14 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates }: + +mk { + package.name = "sel4-pl031-driver"; + dependencies = { + inherit (versions) tock-registers rtcc; + }; +} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.toml b/crates/drivers/pl031/Cargo.toml similarity index 91% rename from crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.toml rename to crates/drivers/pl031/Cargo.toml index f323ffa80..eb2a81758 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.toml +++ b/crates/drivers/pl031/Cargo.toml @@ -10,11 +10,12 @@ # [package] -name = "banscii-pl011-driver-core" +name = "sel4-pl031-driver" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" [dependencies] +rtcc = "0.3.2" tock-registers = "0.8.1" diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/core/src/device.rs b/crates/drivers/pl031/src/device.rs similarity index 96% rename from crates/examples/microkit/http-server/pds/pl031-driver/core/src/device.rs rename to crates/drivers/pl031/src/device.rs index 9e104031d..6b52bcdaf 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/core/src/device.rs +++ b/crates/drivers/pl031/src/device.rs @@ -58,7 +58,7 @@ pub struct Device { #[allow(dead_code)] impl Device { - pub unsafe fn new(ptr: *const ()) -> Self { + pub const unsafe fn new(ptr: *const ()) -> Self { let ptr = ptr.cast::(); Self { ptr } } diff --git a/crates/drivers/pl031/src/lib.rs b/crates/drivers/pl031/src/lib.rs new file mode 100644 index 000000000..517ba356e --- /dev/null +++ b/crates/drivers/pl031/src/lib.rs @@ -0,0 +1,54 @@ +// +// Copyright 2023, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use rtcc::{DateTime, DateTimeAccess, NaiveDateTime}; + +mod device; + +use device::Device; + +pub struct Driver { + device: Device, +} + +impl Driver { + #[allow(clippy::missing_safety_doc)] + pub const unsafe fn new_uninit(ptr: *mut ()) -> Self { + Self { + device: Device::new(ptr), + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(ptr: *mut ()) -> Self { + let mut this = Self::new_uninit(ptr); + this.init(); + this + } + + pub fn init(&mut self) {} +} + +impl DateTimeAccess for Driver { + type Error = Error; + + fn datetime(&mut self) -> Result { + Ok(DateTime::from_timestamp(self.device.get_data().into(), 0) + .unwrap() + .naive_utc()) + } + + fn set_datetime(&mut self, _datetime: &NaiveDateTime) -> Result<(), Self::Error> { + Err(Error::UnsupportedOperation) + } +} + +#[derive(Debug, Clone)] +pub enum Error { + UnsupportedOperation, +} diff --git a/crates/drivers/sp804/Cargo.nix b/crates/drivers/sp804/Cargo.nix new file mode 100644 index 000000000..28f8145b9 --- /dev/null +++ b/crates/drivers/sp804/Cargo.nix @@ -0,0 +1,15 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates }: + +mk { + package.name = "sel4-sp804-driver"; + dependencies = { + inherit (versions) tock-registers; + inherit (localCrates) sel4-driver-interfaces; + }; +} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.toml b/crates/drivers/sp804/Cargo.toml similarity index 83% rename from crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.toml rename to crates/drivers/sp804/Cargo.toml index db5857886..4471aa3b3 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.toml +++ b/crates/drivers/sp804/Cargo.toml @@ -10,12 +10,12 @@ # [package] -name = "microkit-http-server-example-pl031-driver-core" +name = "sel4-sp804-driver" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" [dependencies] -log = "0.4.17" +sel4-driver-interfaces = { path = "../../sel4-driver-interfaces" } tock-registers = "0.8.1" diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/core/src/device.rs b/crates/drivers/sp804/src/device.rs similarity index 96% rename from crates/examples/microkit/http-server/pds/sp804-driver/core/src/device.rs rename to crates/drivers/sp804/src/device.rs index ed2a5f393..3e8fe6bce 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/core/src/device.rs +++ b/crates/drivers/sp804/src/device.rs @@ -73,7 +73,7 @@ pub struct Device { } impl Device { - pub unsafe fn new(ptr: *const ()) -> Self { + pub const unsafe fn new(ptr: *const ()) -> Self { let ptr = ptr.cast::(); Device { timer_1: Timer::new(ptr.offset(0)), @@ -96,7 +96,7 @@ pub struct Timer { #[allow(dead_code)] impl Timer { - pub unsafe fn new(ptr: *const TimerRegisterBlock) -> Self { + pub const unsafe fn new(ptr: *const TimerRegisterBlock) -> Self { Self { ptr } } diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/core/src/lib.rs b/crates/drivers/sp804/src/lib.rs similarity index 77% rename from crates/examples/microkit/http-server/pds/sp804-driver/core/src/lib.rs rename to crates/drivers/sp804/src/lib.rs index 98d15d653..8addd5734 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/core/src/lib.rs +++ b/crates/drivers/sp804/src/lib.rs @@ -6,10 +6,13 @@ #![no_std] +use core::convert::Infallible; use core::time::Duration; - use tock_registers::interfaces::ReadWriteable; +use sel4_driver_interfaces::timer::{Clock, ErrorType, Timer as TimerTrait}; +use sel4_driver_interfaces::HandleInterrupt; + mod device; use device::{Control, Device, Timer}; @@ -23,18 +26,23 @@ pub struct Driver { impl Driver { #[allow(clippy::missing_safety_doc)] - pub unsafe fn new(ptr: *mut (), freq: u64) -> Self { - let mut this = Self { + pub const unsafe fn new_uninit(ptr: *mut (), freq: u64) -> Self { + Self { device: Device::new(ptr), freq, high_bits: 0, most_recent_value: !0, - }; + } + } + + #[allow(clippy::missing_safety_doc)] + pub unsafe fn new(ptr: *mut (), freq: u64) -> Self { + let mut this = Self::new_uninit(ptr, freq); this.init(); this } - fn init(&mut self) { + pub fn init(&mut self) { let control_common = Control::TimerEn::Disabled + Control::TimerPre::Div256 + Control::TimerSize::Use32Bit; @@ -82,12 +90,6 @@ impl Driver { let _ = self.current_value_checking_for_overflow(); } - pub fn now(&mut self) -> Duration { - let value = self.current_value_checking_for_overflow(); - let ticks = ((u64::from(self.high_bits) + 1) << 32) - u64::from(value); - self.ticks_to_duration(ticks) - } - fn ticks_to_duration(&self, ticks: u64) -> Duration { Duration::from_nanos( u64::try_from((u128::from(ticks) * 1_000_000_000) / u128::from(self.scaled_freq())) @@ -98,31 +100,50 @@ impl Driver { fn duration_to_ticks(&self, d: Duration) -> u128 { (d.as_nanos() * u128::from(self.scaled_freq())) / 1_000_000_000 } +} - pub fn handle_interrupt(&mut self) { +impl HandleInterrupt for Driver { + fn handle_interrupt(&mut self) { if self.timer_for_reading().masked_interrupt_status() { self.check_for_overflow(); self.timer_for_reading().clear_interrupt(); } if self.timer_for_writing().masked_interrupt_status() { - self.clear_timeout(); + self.clear_timeout().unwrap(); self.timer_for_writing().clear_interrupt(); } } +} + +impl ErrorType for Driver { + type Error = Infallible; +} + +impl Clock for Driver { + fn get_time(&mut self) -> Result { + let value = self.current_value_checking_for_overflow(); + let ticks = ((u64::from(self.high_bits) + 1) << 32) - u64::from(value); + let t = self.ticks_to_duration(ticks); + Ok(t) + } +} - pub fn set_timeout(&self, relative: Duration) { - self.clear_timeout(); +impl TimerTrait for Driver { + fn set_timeout(&mut self, relative: Duration) -> Result<(), Self::Error> { + self.clear_timeout().unwrap(); self.timer_for_writing() .set_load(self.duration_to_ticks(relative).try_into().unwrap()); self.timer_for_writing() .control() .modify(Control::TimerEn::Enabled + Control::IntEnable::Enabled); + Ok(()) } - pub fn clear_timeout(&self) { + fn clear_timeout(&mut self) -> Result<(), Self::Error> { self.timer_for_writing() .control() .modify(Control::TimerEn::Disabled + Control::IntEnable::Disabled); self.timer_for_writing().set_load(0); + Ok(()) } } diff --git a/crates/drivers/virtio/blk/Cargo.nix b/crates/drivers/virtio/blk/Cargo.nix new file mode 100644 index 000000000..7e0846273 --- /dev/null +++ b/crates/drivers/virtio/blk/Cargo.nix @@ -0,0 +1,16 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates, virtioDriversWith }: + +mk { + package.name = "sel4-virtio-blk"; + dependencies = { + inherit (versions) log; + virtio-drivers = virtioDriversWith []; + inherit (localCrates) sel4-driver-interfaces; + }; +} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.toml b/crates/drivers/virtio/blk/Cargo.toml similarity index 72% rename from crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.toml rename to crates/drivers/virtio/blk/Cargo.toml index c444d2347..2b22f2fb4 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.toml +++ b/crates/drivers/virtio/blk/Cargo.toml @@ -10,11 +10,13 @@ # [package] -name = "microkit-http-server-example-pl031-driver-interface-types" +name = "sel4-virtio-blk" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" [dependencies] -serde = { version = "1.0.147", default-features = false } +log = "0.4.17" +sel4-driver-interfaces = { path = "../../../sel4-driver-interfaces" } +virtio-drivers = { version = "0.7.2", default-features = false } diff --git a/crates/drivers/virtio/blk/src/lib.rs b/crates/drivers/virtio/blk/src/lib.rs new file mode 100644 index 000000000..95a188682 --- /dev/null +++ b/crates/drivers/virtio/blk/src/lib.rs @@ -0,0 +1,30 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::convert::Infallible; +use core::ops::Deref; + +use sel4_driver_interfaces::block::GetBlockDeviceLayout; +use virtio_drivers::device::blk::{VirtIOBlk, SECTOR_SIZE}; +use virtio_drivers::{transport::Transport, Hal}; + +pub struct GetBlockDeviceLayoutWrapper(pub T); + +impl>> GetBlockDeviceLayout + for GetBlockDeviceLayoutWrapper +{ + type Error = Infallible; + + fn get_block_size(&mut self) -> Result { + Ok(SECTOR_SIZE) + } + + fn get_num_blocks(&mut self) -> Result { + Ok(self.0.deref().capacity()) + } +} diff --git a/crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.nix b/crates/drivers/virtio/hal-impl/Cargo.nix similarity index 68% rename from crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.nix rename to crates/drivers/virtio/hal-impl/Cargo.nix index 6e807e8c5..cdcdf2b8f 100644 --- a/crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.nix +++ b/crates/drivers/virtio/hal-impl/Cargo.nix @@ -4,12 +4,11 @@ # SPDX-License-Identifier: BSD-2-Clause # -{ mk, localCrates, versions, virtioDriversWith }: +{ mk, localCrates, virtioDriversWith }: mk { - package.name = "microkit-http-server-example-virtio-hal-impl"; + package.name = "sel4-virtio-hal-impl"; dependencies = { - inherit (versions) log; virtio-drivers = virtioDriversWith []; inherit (localCrates) sel4-sync diff --git a/crates/drivers/virtio/hal-impl/Cargo.toml b/crates/drivers/virtio/hal-impl/Cargo.toml new file mode 100644 index 000000000..f0fede9e1 --- /dev/null +++ b/crates/drivers/virtio/hal-impl/Cargo.toml @@ -0,0 +1,24 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-virtio-hal-impl" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2021" +license = "BSD-2-Clause" + +[dependencies] +sel4-bounce-buffer-allocator = { path = "../../../sel4-bounce-buffer-allocator" } +sel4-externally-shared = { path = "../../../sel4-externally-shared" } +sel4-immediate-sync-once-cell = { path = "../../../sel4-immediate-sync-once-cell" } +sel4-sync = { path = "../../../sel4-sync" } +virtio-drivers = { version = "0.7.2", default-features = false } diff --git a/crates/examples/microkit/http-server/helpers/virtio-hal-impl/src/lib.rs b/crates/drivers/virtio/hal-impl/src/lib.rs similarity index 100% rename from crates/examples/microkit/http-server/helpers/virtio-hal-impl/src/lib.rs rename to crates/drivers/virtio/hal-impl/src/lib.rs diff --git a/crates/drivers/virtio/net/Cargo.nix b/crates/drivers/virtio/net/Cargo.nix new file mode 100644 index 000000000..c0909125a --- /dev/null +++ b/crates/drivers/virtio/net/Cargo.nix @@ -0,0 +1,25 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: MIT +# + +{ mk, mkDefaultFrontmatterWithReuseArgs, defaultReuseFrontmatterArgs, versions, localCrates, smoltcpWith, virtioDriversWith, authors }: + +mk rec { + nix.frontmatter = mkDefaultFrontmatterWithReuseArgs (defaultReuseFrontmatterArgs // { + licenseID = package.license; + }); + package.name = "sel4-virtio-net"; + package.authors = with authors; [ + nspin + "Runji Wang " + ]; + package.license = "MIT"; + dependencies = { + inherit (versions) log; + smoltcp = smoltcpWith []; + virtio-drivers = virtioDriversWith [ "alloc" ]; + inherit (localCrates) sel4-driver-interfaces; + }; +} diff --git a/crates/drivers/virtio/net/Cargo.toml b/crates/drivers/virtio/net/Cargo.toml new file mode 100644 index 000000000..c20b27318 --- /dev/null +++ b/crates/drivers/virtio/net/Cargo.toml @@ -0,0 +1,27 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: MIT +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-virtio-net" +version = "0.1.0" +authors = ["Nick Spinale ", "Runji Wang "] +edition = "2021" +license = "MIT" + +[dependencies] +log = "0.4.17" +sel4-driver-interfaces = { path = "../../../sel4-driver-interfaces" } +virtio-drivers = { version = "0.7.2", default-features = false, features = ["alloc"] } + +[dependencies.smoltcp] +version = "0.10.0" +default-features = false +features = ["proto-ipv4", "proto-dhcpv4", "proto-dns", "socket-dhcpv4", "socket-dns", "socket-tcp"] diff --git a/crates/drivers/virtio/net/src/lib.rs b/crates/drivers/virtio/net/src/lib.rs new file mode 100644 index 000000000..528e90107 --- /dev/null +++ b/crates/drivers/virtio/net/src/lib.rs @@ -0,0 +1,115 @@ +// +// Copyright 2023, Colias Group, LLC +// Copyright (c) 2019-2020 rCore Developers +// +// SPDX-License-Identifier: MIT +// + +#![no_std] + +extern crate alloc; + +use alloc::rc::Rc; +use core::cell::RefCell; +use core::convert::Infallible; + +use log::trace; +use sel4_driver_interfaces::net::{GetNetDeviceMeta, MacAddress}; +use sel4_driver_interfaces::HandleInterrupt; +use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken}; +use smoltcp::time::Instant; +use virtio_drivers::device::net::{RxBuffer, VirtIONet}; +use virtio_drivers::{transport::Transport, Error, Hal}; + +pub const NET_QUEUE_SIZE: usize = 16; + +pub type DeviceImpl = VirtIONet; + +pub struct DeviceWrapper { + inner: Rc>>, +} + +impl DeviceWrapper { + pub fn new(dev: DeviceImpl) -> Self { + DeviceWrapper { + inner: Rc::new(RefCell::new(dev)), + } + } +} + +impl HandleInterrupt for DeviceWrapper { + fn handle_interrupt(&mut self) { + self.inner.borrow_mut().ack_interrupt(); + } +} + +impl GetNetDeviceMeta for DeviceWrapper { + type Error = Infallible; + + fn get_mac_address(&mut self) -> Result { + Ok(MacAddress(self.inner.borrow().mac_address())) + } +} + +impl Device for DeviceWrapper { + type RxToken<'a> = VirtioRxToken where Self: 'a; + type TxToken<'a> = VirtioTxToken where Self: 'a; + + fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { + match self.inner.borrow_mut().receive() { + Ok(buf) => Some(( + VirtioRxToken(self.inner.clone(), buf), + VirtioTxToken(self.inner.clone()), + )), + Err(Error::NotReady) => None, + Err(err) => panic!("receive failed: {}", err), + } + } + + fn transmit(&mut self, _timestamp: Instant) -> Option> { + Some(VirtioTxToken(self.inner.clone())) + } + + fn capabilities(&self) -> DeviceCapabilities { + let mut caps = DeviceCapabilities::default(); + caps.max_transmission_unit = 1536; + caps.max_burst_size = Some(1); + caps.medium = Medium::Ethernet; + caps + } +} + +pub struct VirtioRxToken(Rc>>, RxBuffer); + +impl RxToken for VirtioRxToken { + fn consume(self, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + let mut rx_buf = self.1; + trace!( + "RECV {} bytes: {:02X?}", + rx_buf.packet_len(), + rx_buf.packet() + ); + let result = f(rx_buf.packet_mut()); + self.0.borrow_mut().recycle_rx_buffer(rx_buf).unwrap(); + result + } +} + +pub struct VirtioTxToken(Rc>>); + +impl TxToken for VirtioTxToken { + fn consume(self, len: usize, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + let mut dev = self.0.borrow_mut(); + let mut tx_buf = dev.new_tx_buffer(len); + let result = f(tx_buf.packet_mut()); + trace!("SEND {} bytes: {:02X?}", len, tx_buf.packet()); + dev.send(tx_buf).unwrap(); + result + } +} diff --git a/crates/examples/microkit/banscii/banscii.system b/crates/examples/microkit/banscii/banscii.system.template similarity index 74% rename from crates/examples/microkit/banscii/banscii.system rename to crates/examples/microkit/banscii/banscii.system.template index 6212de86f..5790d7ab0 100644 --- a/crates/examples/microkit/banscii/banscii.system +++ b/crates/examples/microkit/banscii/banscii.system.template @@ -6,15 +6,15 @@ --> - + - - - - + + + + @@ -30,7 +30,7 @@ - + diff --git a/crates/examples/microkit/banscii/generate_system_description.py b/crates/examples/microkit/banscii/generate_system_description.py new file mode 100644 index 000000000..8244b917e --- /dev/null +++ b/crates/examples/microkit/banscii/generate_system_description.py @@ -0,0 +1,38 @@ +# +# Copyright 2024, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# + +import argparse +import json +import sys +from jinja2 import Template + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('--template', type=argparse.FileType('r'), required=True) + parser.add_argument('--board', required=True) + parser.add_argument('-o', type=argparse.FileType('w'), required=True) + args = parser.parse_args() + run(args) + +def run(args): + template = Template(args.template.read()) + context = mk_context(args.board) + rendered = template.render(context) + args.o.write(rendered) + +def mk_context(board): + context = {} + + if board == 'qemu_virt_aarch64': + context['serial_mmio_phys_addr'] = 0x9000000 + context['serial_irq'] = 33 + else: + raise Exception('unsupported configuration') + + return context + +if __name__ == '__main__': + main() diff --git a/crates/examples/microkit/banscii/pds/assistant/Cargo.nix b/crates/examples/microkit/banscii/pds/assistant/Cargo.nix index f17dccdd7..b7e33d49b 100644 --- a/crates/examples/microkit/banscii/pds/assistant/Cargo.nix +++ b/crates/examples/microkit/banscii/pds/assistant/Cargo.nix @@ -4,16 +4,17 @@ # SPDX-License-Identifier: BSD-2-Clause # -{ mk, localCrates }: +{ mk, versions, localCrates }: mk { package.name = "banscii-assistant"; dependencies = { + inherit (versions) embedded-hal-nb; hex = { version = "0.4.3"; default-features = false; features = [ "alloc" ]; }; inherit (localCrates) sel4-microkit-message + sel4-microkit-driver-adapters banscii-assistant-core - banscii-pl011-driver-interface-types banscii-artist-interface-types ; sel4-externally-shared = localCrates.sel4-externally-shared // { features = [ "unstable" ]; }; diff --git a/crates/examples/microkit/banscii/pds/assistant/Cargo.toml b/crates/examples/microkit/banscii/pds/assistant/Cargo.toml index 6f6c1bc6f..60acfd2e1 100644 --- a/crates/examples/microkit/banscii/pds/assistant/Cargo.toml +++ b/crates/examples/microkit/banscii/pds/assistant/Cargo.toml @@ -19,9 +19,10 @@ license = "BSD-2-Clause" [dependencies] banscii-artist-interface-types = { path = "../artist/interface-types" } banscii-assistant-core = { path = "core" } -banscii-pl011-driver-interface-types = { path = "../pl011-driver/interface-types" } +embedded-hal-nb = "1.0" hex = { version = "0.4.3", default-features = false, features = ["alloc"] } sel4-externally-shared = { path = "../../../../../sel4-externally-shared", features = ["unstable"] } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } [dependencies.sel4-microkit] diff --git a/crates/examples/microkit/banscii/pds/assistant/src/main.rs b/crates/examples/microkit/banscii/pds/assistant/src/main.rs index e95f19824..f74b99ee7 100644 --- a/crates/examples/microkit/banscii/pds/assistant/src/main.rs +++ b/crates/examples/microkit/banscii/pds/assistant/src/main.rs @@ -11,11 +11,12 @@ extern crate alloc; use alloc::vec; use alloc::vec::Vec; -use core::fmt; use core::fmt::Write; use core::mem; use core::str; +use embedded_hal_nb::serial::{self, Read as _, Write as _}; + use sel4_externally_shared::{ access::{ReadOnly, ReadWrite}, ExternallySharedRef, ExternallySharedRefExt, @@ -23,13 +24,15 @@ use sel4_externally_shared::{ use sel4_microkit::{ memory_region_symbol, protection_domain, Channel, Handler, Infallible, MessageInfo, }; +use sel4_microkit_driver_adapters::serial::client::{ + Client as SerialClient, Error as SerialClientError, +}; use sel4_microkit_message::MessageInfoExt as _; use banscii_artist_interface_types as artist; use banscii_assistant_core::Draft; -use banscii_pl011_driver_interface_types as pl011_driver; -const PL011_DRIVER: Channel = Channel::new(0); +const SERIAL_DRIVER: Channel = Channel::new(0); const ARTIST: Channel = Channel::new(1); const REGION_SIZE: usize = 0x4_000; @@ -48,16 +51,20 @@ fn init() -> impl Handler { ) }; - prompt(); - - HandlerImpl { + let mut this = HandlerImpl { + serial_client: SerialClient::new(SERIAL_DRIVER), region_in, region_out, buffer: Vec::new(), - } + }; + + this.prompt(); + + this } struct HandlerImpl { + serial_client: SerialClient, region_in: ExternallySharedRef<'static, [u8], ReadOnly>, region_out: ExternallySharedRef<'static, [u8], ReadWrite>, buffer: Vec, @@ -68,23 +75,23 @@ impl Handler for HandlerImpl { fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { match channel { - PL011_DRIVER => { - while let Some(b) = get_char() { + SERIAL_DRIVER => { + while let Ok(b) = self.serial_client.read() { if let b'\n' | b'\r' = b { - newline(); + self.newline(); if !self.buffer.is_empty() { self.try_create(); } - prompt(); + self.prompt(); } else { let c = char::from(b); if c.is_ascii() && !c.is_ascii_control() { if self.buffer.len() == MAX_SUBJECT_LEN { - writeln!(PutCharWrite, "\n(char limit reached)").unwrap(); + writeln!(self.writer(), "\n(char limit reached)").unwrap(); self.try_create(); - prompt(); + self.prompt(); } - put_char(b); + self.serial_client.write(b).unwrap(); self.buffer.push(b); } } @@ -107,7 +114,7 @@ impl HandlerImpl { self.create(subject); } Err(_) => { - writeln!(PutCharWrite, "error: input is not valid utf-8").unwrap(); + writeln!(self.writer(), "error: input is not valid utf-8").unwrap(); } }; self.buffer.clear(); @@ -158,62 +165,36 @@ impl HandlerImpl { buf }; - newline(); + self.newline(); for row in 0..height { for col in 0..width { let i = row * width + col; let b = pixel_data[i]; - put_char(b); + self.serial_client.write(b).unwrap(); } - newline(); + self.newline(); } - newline(); + self.newline(); - writeln!(PutCharWrite, "Signature:").unwrap(); + writeln!(self.writer(), "Signature:").unwrap(); for line in signature.chunks(32) { - writeln!(PutCharWrite, "{}", hex::encode(line)).unwrap(); + writeln!(self.writer(), "{}", hex::encode(line)).unwrap(); } - newline(); + self.newline(); } -} - -fn prompt() { - write!(PutCharWrite, "banscii> ").unwrap(); -} -fn newline() { - writeln!(PutCharWrite).unwrap(); -} - -fn get_char() -> Option { - let req = pl011_driver::Request::GetChar; - let resp: pl011_driver::GetCharSomeResponse = PL011_DRIVER - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_using_postcard() - .unwrap(); - resp.val -} - -fn put_char(val: u8) { - let req = pl011_driver::Request::PutChar { val }; - PL011_DRIVER - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_empty() - .unwrap(); -} - -fn put_str(s: &str) { - s.as_bytes().iter().copied().for_each(put_char) -} + fn prompt(&mut self) { + write!(self.writer(), "banscii> ").unwrap(); + } -struct PutCharWrite; + fn newline(&mut self) { + writeln!(self.writer()).unwrap(); + } -impl fmt::Write for PutCharWrite { - fn write_str(&mut self, s: &str) -> fmt::Result { - put_str(s); - Ok(()) + fn writer(&mut self) -> &mut dyn serial::Write { + &mut self.serial_client as &mut dyn serial::Write } } diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.nix b/crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.nix deleted file mode 100644 index 80a6de944..000000000 --- a/crates/examples/microkit/banscii/pds/pl011-driver/core/Cargo.nix +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, versions }: - -mk { - package.name = "banscii-pl011-driver-core"; - dependencies = { - inherit (versions) tock-registers; - }; -} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/core/src/lib.rs b/crates/examples/microkit/banscii/pds/pl011-driver/core/src/lib.rs deleted file mode 100644 index a90ed7e55..000000000 --- a/crates/examples/microkit/banscii/pds/pl011-driver/core/src/lib.rs +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -mod device; - -use device::Device; - -pub struct Driver { - device: Device, -} - -impl Driver { - #[allow(clippy::missing_safety_doc)] - pub unsafe fn new(ptr: *mut ()) -> Self { - let mut this = Self { - device: Device::new(ptr.cast()), - }; - this.init(); - this - } - - fn init(&mut self) { - self.device.init(); - } - - pub fn put_char(&self, c: u8) { - self.device.put_char(c) - } - - pub fn get_char(&self) -> Option { - self.device.get_char() - } - - pub fn handle_interrupt(&self) { - self.device.clear_all_interrupts() - } -} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/src/lib.rs b/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/src/lib.rs deleted file mode 100644 index d85257074..000000000 --- a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/src/lib.rs +++ /dev/null @@ -1,20 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - PutChar { val: u8 }, - GetChar, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetCharSomeResponse { - pub val: Option, -} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/src/main.rs b/crates/examples/microkit/banscii/pds/pl011-driver/src/main.rs deleted file mode 100644 index baccc5de6..000000000 --- a/crates/examples/microkit/banscii/pds/pl011-driver/src/main.rs +++ /dev/null @@ -1,92 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] -#![no_main] - -use heapless::Deque; - -use sel4_microkit::{ - memory_region_symbol, protection_domain, Channel, Handler, Infallible, MessageInfo, -}; -use sel4_microkit_message::MessageInfoExt as _; - -use banscii_pl011_driver_core::Driver; -use banscii_pl011_driver_interface_types::*; - -const DEVICE: Channel = Channel::new(0); -const ASSISTANT: Channel = Channel::new(1); - -#[protection_domain] -fn init() -> HandlerImpl { - let driver = - unsafe { Driver::new(memory_region_symbol!(pl011_register_block: *mut ()).as_ptr()) }; - HandlerImpl { - driver, - buffer: Deque::new(), - notify: true, - } -} - -struct HandlerImpl { - driver: Driver, - buffer: Deque, - notify: bool, -} - -impl Handler for HandlerImpl { - type Error = Infallible; - - fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { - match channel { - DEVICE => { - while let Some(c) = self.driver.get_char() { - if self.buffer.push_back(c).is_err() { - break; - } - } - self.driver.handle_interrupt(); - DEVICE.irq_ack().unwrap(); - if self.notify { - ASSISTANT.notify(); - self.notify = false; - } - } - _ => { - unreachable!() - } - } - Ok(()) - } - - fn protected( - &mut self, - channel: Channel, - msg_info: MessageInfo, - ) -> Result { - Ok(match channel { - ASSISTANT => match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::PutChar { val } => { - self.driver.put_char(val); - MessageInfo::send_empty() - } - Request::GetChar => { - let val = self.buffer.pop_front(); - if val.is_some() { - self.notify = true; - } - MessageInfo::send_using_postcard(GetCharSomeResponse { val }).unwrap() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - }, - _ => { - unreachable!() - } - }) - } -} diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/Cargo.nix b/crates/examples/microkit/banscii/pds/serial-driver/Cargo.nix similarity index 54% rename from crates/examples/microkit/banscii/pds/pl011-driver/Cargo.nix rename to crates/examples/microkit/banscii/pds/serial-driver/Cargo.nix index 37c8a91b6..1aa5bfcb3 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/Cargo.nix +++ b/crates/examples/microkit/banscii/pds/serial-driver/Cargo.nix @@ -7,14 +7,17 @@ { mk, localCrates, versions }: mk { - package.name = "banscii-pl011-driver"; + package.name = "banscii-serial-driver"; dependencies = { - inherit (versions) heapless; inherit (localCrates) sel4-microkit-message - banscii-pl011-driver-core - banscii-pl011-driver-interface-types + sel4-microkit-driver-adapters + ; sel4-microkit = localCrates.sel4-microkit // { default-features = false; }; + sel4-pl011-driver = localCrates.sel4-pl011-driver // { optional = true; }; + }; + features = { + board-qemu_virt_aarch64 = [ "sel4-pl011-driver" ]; }; } diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/Cargo.toml b/crates/examples/microkit/banscii/pds/serial-driver/Cargo.toml similarity index 70% rename from crates/examples/microkit/banscii/pds/pl011-driver/Cargo.toml rename to crates/examples/microkit/banscii/pds/serial-driver/Cargo.toml index 28db6aa18..d3c664a5e 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/Cargo.toml +++ b/crates/examples/microkit/banscii/pds/serial-driver/Cargo.toml @@ -10,15 +10,17 @@ # [package] -name = "banscii-pl011-driver" +name = "banscii-serial-driver" version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "BSD-2-Clause" +[features] +board-qemu_virt_aarch64 = ["sel4-pl011-driver"] + [dependencies] -banscii-pl011-driver-core = { path = "core" } -banscii-pl011-driver-interface-types = { path = "interface-types" } -heapless = "0.7.16" sel4-microkit = { path = "../../../../../sel4-microkit", default-features = false } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } +sel4-pl011-driver = { path = "../../../../../drivers/pl011", optional = true } diff --git a/crates/examples/microkit/banscii/pds/serial-driver/src/main.rs b/crates/examples/microkit/banscii/pds/serial-driver/src/main.rs new file mode 100644 index 000000000..acef51227 --- /dev/null +++ b/crates/examples/microkit/banscii/pds/serial-driver/src/main.rs @@ -0,0 +1,24 @@ +// +// Copyright 2023, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] +#![no_main] + +use sel4_microkit::{memory_region_symbol, protection_domain, Channel, Handler}; +use sel4_microkit_driver_adapters::serial::driver::HandlerImpl; + +#[cfg(feature = "board-qemu_virt_aarch64")] +use sel4_pl011_driver::Driver; + +const DEVICE: Channel = Channel::new(0); +const ASSISTANT: Channel = Channel::new(1); + +#[protection_domain] +fn init() -> impl Handler { + let driver = + unsafe { Driver::new(memory_region_symbol!(serial_register_block: *mut ()).as_ptr()) }; + HandlerImpl::new(driver, DEVICE, ASSISTANT) +} diff --git a/crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.toml b/crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.toml deleted file mode 100644 index 65d683681..000000000 --- a/crates/examples/microkit/http-server/helpers/virtio-hal-impl/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# -# -# This file is generated from './Cargo.nix'. You can edit this file directly -# if you are not using this project's Cargo manifest management tools. -# See 'hacking/cargo-manifest-management/README.md' for more information. -# - -[package] -name = "microkit-http-server-example-virtio-hal-impl" -version = "0.1.0" -authors = ["Nick Spinale "] -edition = "2021" -license = "BSD-2-Clause" - -[dependencies] -log = "0.4.17" -sel4-bounce-buffer-allocator = { path = "../../../../../sel4-bounce-buffer-allocator" } -sel4-externally-shared = { path = "../../../../../sel4-externally-shared" } -sel4-immediate-sync-once-cell = { path = "../../../../../sel4-immediate-sync-once-cell" } -sel4-sync = { path = "../../../../../sel4-sync" } -virtio-drivers = { version = "0.5.0", default-features = false } diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.nix b/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.nix index 08c06b1f2..829adf1c2 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.nix @@ -10,9 +10,8 @@ mk { package.name = "microkit-http-server-example-pl031-driver"; dependencies = { inherit (localCrates) - sel4-microkit-message - microkit-http-server-example-pl031-driver-core - microkit-http-server-example-pl031-driver-interface-types + sel4-pl031-driver + sel4-microkit-driver-adapters ; sel4-microkit = localCrates.sel4-microkit // { default-features = false; }; }; diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.toml b/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.toml index e496bcdd3..06302b6f1 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/pl031-driver/Cargo.toml @@ -17,7 +17,6 @@ edition = "2021" license = "BSD-2-Clause" [dependencies] -microkit-http-server-example-pl031-driver-core = { path = "core" } -microkit-http-server-example-pl031-driver-interface-types = { path = "interface-types" } sel4-microkit = { path = "../../../../../sel4-microkit", default-features = false } -sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } +sel4-pl031-driver = { path = "../../../../../drivers/pl031" } diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.nix b/crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.nix deleted file mode 100644 index e3f64f4d9..000000000 --- a/crates/examples/microkit/http-server/pds/pl031-driver/core/Cargo.nix +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, versions }: - -mk { - package.name = "microkit-http-server-example-pl031-driver-core"; - dependencies = { - inherit (versions) log; - tock-registers = "0.8.1"; - }; -} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/core/src/lib.rs b/crates/examples/microkit/http-server/pds/pl031-driver/core/src/lib.rs deleted file mode 100644 index 429de8f98..000000000 --- a/crates/examples/microkit/http-server/pds/pl031-driver/core/src/lib.rs +++ /dev/null @@ -1,34 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use core::time::Duration; - -mod device; - -use device::Device; - -pub struct Driver { - device: Device, -} - -impl Driver { - #[allow(clippy::missing_safety_doc)] - pub unsafe fn new(ptr: *mut ()) -> Self { - let mut this = Self { - device: Device::new(ptr), - }; - this.init(); - this - } - - fn init(&mut self) {} - - pub fn now(&mut self) -> Duration { - Duration::from_secs(self.device.get_data().into()) - } -} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.nix b/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.nix deleted file mode 100644 index fd5d0c969..000000000 --- a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/Cargo.nix +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, serdeWith }: - -mk { - package.name = "microkit-http-server-example-pl031-driver-interface-types"; - dependencies = { - serde = serdeWith []; - }; -} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/src/lib.rs b/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/src/lib.rs deleted file mode 100644 index 064117713..000000000 --- a/crates/examples/microkit/http-server/pds/pl031-driver/interface-types/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use serde::{Deserialize, Serialize}; - -pub type Seconds = u32; - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - Now, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct NowResponse { - pub unix_time: Seconds, -} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/src/config.rs b/crates/examples/microkit/http-server/pds/pl031-driver/src/config.rs deleted file mode 100644 index eff7034a2..000000000 --- a/crates/examples/microkit/http-server/pds/pl031-driver/src/config.rs +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![allow(dead_code)] - -pub mod channels { - use sel4_microkit::Channel; - - pub const DEVICE: Channel = Channel::new(0); - pub const CLIENT: Channel = Channel::new(1); -} diff --git a/crates/examples/microkit/http-server/pds/pl031-driver/src/main.rs b/crates/examples/microkit/http-server/pds/pl031-driver/src/main.rs index 32663d45f..d4c8d1e2c 100644 --- a/crates/examples/microkit/http-server/pds/pl031-driver/src/main.rs +++ b/crates/examples/microkit/http-server/pds/pl031-driver/src/main.rs @@ -7,52 +7,15 @@ #![no_std] #![no_main] -use sel4_microkit::{ - memory_region_symbol, protection_domain, Channel, Handler, Infallible, MessageInfo, -}; -use sel4_microkit_message::MessageInfoExt as _; +use sel4_microkit::{memory_region_symbol, protection_domain, Channel, Handler}; +use sel4_microkit_driver_adapters::rtc::driver::HandlerImpl; +use sel4_pl031_driver::Driver; -use microkit_http_server_example_pl031_driver_core::Driver; -use microkit_http_server_example_pl031_driver_interface_types::*; - -mod config; - -use config::channels; +const _DEVICE: Channel = Channel::new(0); +const CLIENT: Channel = Channel::new(1); #[protection_domain] -fn init() -> HandlerImpl { +fn init() -> impl Handler { let driver = unsafe { Driver::new(memory_region_symbol!(pl031_mmio_vaddr: *mut ()).as_ptr()) }; - HandlerImpl { driver } -} - -struct HandlerImpl { - driver: Driver, -} - -impl Handler for HandlerImpl { - type Error = Infallible; - - fn protected( - &mut self, - channel: Channel, - msg_info: MessageInfo, - ) -> Result { - Ok(match channel { - channels::CLIENT => match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::Now => { - let now = self.driver.now(); - MessageInfo::send_using_postcard(NowResponse { - unix_time: now.as_secs().try_into().unwrap(), - }) - .unwrap() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - }, - _ => { - unreachable!() - } - }) - } + HandlerImpl::new(driver, CLIENT) } diff --git a/crates/examples/microkit/http-server/pds/server/Cargo.nix b/crates/examples/microkit/http-server/pds/server/Cargo.nix index e47df6ebc..67d71ad03 100644 --- a/crates/examples/microkit/http-server/pds/server/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/server/Cargo.nix @@ -10,7 +10,7 @@ mk { package.name = "microkit-http-server-example-server"; dependencies = { - inherit (versions) log; + inherit (versions) log rtcc lock_api; futures = { version = versions.futures; @@ -29,9 +29,12 @@ mk { inherit (localCrates) sel4 + sel4-sync sel4-logging sel4-immediate-sync-once-cell sel4-microkit-message + sel4-microkit-driver-adapters + sel4-driver-interfaces sel4-async-single-threaded-executor sel4-async-network sel4-async-time @@ -43,10 +46,6 @@ mk { sel4-shared-ring-buffer-block-io-types sel4-async-block-io sel4-async-block-io-fat - microkit-http-server-example-pl031-driver-interface-types - microkit-http-server-example-sp804-driver-interface-types - microkit-http-server-example-virtio-blk-driver-interface-types - microkit-http-server-example-virtio-net-driver-interface-types ; sel4-newlib = localCrates.sel4-newlib // { diff --git a/crates/examples/microkit/http-server/pds/server/Cargo.toml b/crates/examples/microkit/http-server/pds/server/Cargo.toml index f6c6e7b36..ec61c12bf 100644 --- a/crates/examples/microkit/http-server/pds/server/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/server/Cargo.toml @@ -19,34 +19,27 @@ license = "BSD-2-Clause" [dependencies] async-unsync = { version = "0.2.2", default-features = false } futures = { version = "0.3.28", default-features = false, features = ["async-await", "alloc"] } +lock_api = "0.4.12" log = "0.4.17" microkit-http-server-example-server-core = { path = "core", features = [] } +rtcc = "0.3.2" sel4 = { path = "../../../../../sel4" } sel4-async-block-io = { path = "../../../../../sel4-async/block-io" } sel4-async-block-io-fat = { path = "../../../../../sel4-async/block-io/fat" } sel4-async-network = { path = "../../../../../sel4-async/network" } sel4-async-time = { path = "../../../../../sel4-async/time" } sel4-bounce-buffer-allocator = { path = "../../../../../sel4-bounce-buffer-allocator" } +sel4-driver-interfaces = { path = "../../../../../sel4-driver-interfaces" } sel4-externally-shared = { path = "../../../../../sel4-externally-shared", features = ["unstable"] } sel4-immediate-sync-once-cell = { path = "../../../../../sel4-immediate-sync-once-cell" } sel4-logging = { path = "../../../../../sel4-logging" } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } sel4-newlib = { path = "../../../../../sel4-newlib", features = ["nosys", "all-symbols"] } sel4-shared-ring-buffer = { path = "../../../../../sel4-shared-ring-buffer" } sel4-shared-ring-buffer-block-io = { path = "../../../../../sel4-shared-ring-buffer/block-io" } sel4-shared-ring-buffer-smoltcp = { path = "../../../../../sel4-shared-ring-buffer/smoltcp" } - -[dependencies.microkit-http-server-example-pl031-driver-interface-types] -path = "../pl031-driver/interface-types" - -[dependencies.microkit-http-server-example-sp804-driver-interface-types] -path = "../sp804-driver/interface-types" - -[dependencies.microkit-http-server-example-virtio-blk-driver-interface-types] -path = "../virtio-blk-driver/interface-types" - -[dependencies.microkit-http-server-example-virtio-net-driver-interface-types] -path = "../virtio-net-driver/interface-types" +sel4-sync = { path = "../../../../../sel4-sync" } [dependencies.sel4-async-single-threaded-executor] path = "../../../../../sel4-async/single-threaded-executor" diff --git a/crates/examples/microkit/http-server/pds/server/core/Cargo.nix b/crates/examples/microkit/http-server/pds/server/core/Cargo.nix index 21b9d43bb..ff9f6ad08 100644 --- a/crates/examples/microkit/http-server/pds/server/core/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/server/core/Cargo.nix @@ -9,7 +9,7 @@ mk { package.name = "microkit-http-server-example-server-core"; dependencies = { - inherit (versions) log webpki-roots; + inherit (versions) log embedded-io-async webpki-roots; futures = { version = versions.futures; diff --git a/crates/examples/microkit/http-server/pds/server/core/Cargo.toml b/crates/examples/microkit/http-server/pds/server/core/Cargo.toml index aa4c68936..591033ea9 100644 --- a/crates/examples/microkit/http-server/pds/server/core/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/server/core/Cargo.toml @@ -17,6 +17,7 @@ edition = "2021" license = "BSD-2-Clause" [dependencies] +embedded-io-async = "0.6.1" futures = { version = "0.3.28", default-features = false, features = ["async-await", "alloc"] } httparse = { version = "1.8.0", default-features = false } log = "0.4.17" diff --git a/crates/examples/microkit/http-server/pds/server/core/src/lib.rs b/crates/examples/microkit/http-server/pds/server/core/src/lib.rs index 923c2d3b6..f089d9ae0 100644 --- a/crates/examples/microkit/http-server/pds/server/core/src/lib.rs +++ b/crates/examples/microkit/http-server/pds/server/core/src/lib.rs @@ -14,6 +14,7 @@ use alloc::sync::Arc; use alloc::vec; use core::time::Duration; +use embedded_io_async::ReadExactError; use futures::future::{self, LocalBoxFuture}; use futures::task::LocalSpawnExt; use rustls::pki_types::{PrivateKeyDer, UnixTime}; @@ -22,7 +23,7 @@ use rustls::ServerConfig; use sel4_async_block_io::{access::ReadOnly, constant_block_sizes, BlockIO}; use sel4_async_block_io_fat as fat; -use sel4_async_io::ReadExactError; +use sel4_async_io::EmbeddedIOAsyncAdapter; use sel4_async_network::{ManagedInterface, TcpSocket, TcpSocketError}; use sel4_async_network_rustls::{Error as AsyncRustlsError, ServerConnector}; use sel4_async_network_rustls_utils::TimeProviderImpl; @@ -118,7 +119,9 @@ async fn use_socket_for_http Result<(), ReadExactError> { socket.accept(HTTP_PORT).await?; - server.handle_connection(&mut socket).await?; + server + .handle_connection(&mut EmbeddedIOAsyncAdapter(&mut socket)) + .await?; socket.close(); Ok(()) } @@ -135,7 +138,9 @@ async fn use_socket_for_https Self { - Self { channel } - } - - pub fn get_num_blocks(&self) -> u64 { - let req = Request::GetNumBlocks; - let resp: GetNumBlocksResponse = self - .channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_using_postcard() - .unwrap(); - resp.num_blocks - } -} diff --git a/crates/examples/microkit/http-server/pds/server/src/handler.rs b/crates/examples/microkit/http-server/pds/server/src/handler.rs index c5961b56c..ff3e7258c 100644 --- a/crates/examples/microkit/http-server/pds/server/src/handler.rs +++ b/crates/examples/microkit/http-server/pds/server/src/handler.rs @@ -11,7 +11,7 @@ use core::pin::Pin; use core::time::Duration; use futures::future::LocalBoxFuture; - +use lock_api::Mutex; use smoltcp::iface::Config; use smoltcp::time::Instant as SmoltcpInstant; @@ -20,10 +20,13 @@ use sel4_async_network::{DhcpOverrides, ManagedInterface}; use sel4_async_single_threaded_executor::{LocalPool, LocalSpawner}; use sel4_async_time::{Instant, TimerManager}; use sel4_bounce_buffer_allocator::Basic; +use sel4_driver_interfaces::timer::{Clock, DefaultTimer, Timer}; use sel4_microkit::{Channel, Handler, Infallible}; +use sel4_microkit_driver_adapters::timer::client::Client as TimerClient; use sel4_shared_ring_buffer_block_io::SharedRingBufferBlockIO; +use sel4_sync::PanickingRawMutex; -use crate::{DeviceImpl, TimerClient}; +use crate::DeviceImpl; pub(crate) enum Never {} @@ -31,7 +34,7 @@ pub(crate) struct HandlerImpl { timer_driver_channel: sel4_microkit::Channel, net_driver_channel: sel4_microkit::Channel, block_driver_channel: sel4_microkit::Channel, - timer: Arc, + timer: Arc>>, net_device: DeviceImpl, shared_block_io: SharedRingBufferBlockIO, shared_timers: TimerManager, @@ -46,7 +49,7 @@ impl HandlerImpl { timer_driver_channel: sel4_microkit::Channel, net_driver_channel: sel4_microkit::Channel, block_driver_channel: sel4_microkit::Channel, - timer: Arc, + timer: Arc>>, mut net_device: DeviceImpl, net_config: Config, shared_block_io: SharedRingBufferBlockIO, @@ -87,16 +90,18 @@ impl HandlerImpl { this } - fn now(&self) -> Instant { + fn now(&mut self) -> Instant { Self::now_with_timer_client(&self.timer) } - fn now_with_timer_client(timer: &TimerClient) -> Instant { - Instant::new(Duration::from_micros(timer.now())) + fn now_with_timer_client( + timer: &Arc>>, + ) -> Instant { + Instant::new(timer.lock().get_time().unwrap()) } - fn set_timeout(&self, d: Duration) { - self.timer.set_timeout(d.as_micros().try_into().unwrap()) + fn set_timeout(&mut self, d: Duration) { + self.timer.lock().set_timeout(d).unwrap() } // TODO focused polling using these args doesn't play nicely with "repoll" mechanism below diff --git a/crates/examples/microkit/http-server/pds/server/src/main.rs b/crates/examples/microkit/http-server/pds/server/src/main.rs index dd5cc17dd..f9418f30e 100644 --- a/crates/examples/microkit/http-server/pds/server/src/main.rs +++ b/crates/examples/microkit/http-server/pds/server/src/main.rs @@ -13,18 +13,27 @@ use alloc::rc::Rc; use alloc::sync::Arc; use core::time::Duration; +use lock_api::Mutex; +use rtcc::DateTimeAccess; use smoltcp::iface::Config; -use smoltcp::phy::{Device, Medium}; +use smoltcp::phy::{Device, DeviceCapabilities, Medium}; use smoltcp::wire::{EthernetAddress, HardwareAddress}; use sel4_async_block_io::{ - constant_block_sizes::BlockSize512, disk::Disk, CachedBlockIO, ConstantBlockSize, + constant_block_sizes::BlockSize512, disk::Disk, BlockSize, CachedBlockIO, ConstantBlockSize, }; use sel4_async_time::Instant; use sel4_bounce_buffer_allocator::{Basic, BounceBufferAllocator}; +use sel4_driver_interfaces::block::GetBlockDeviceLayout; +use sel4_driver_interfaces::net::GetNetDeviceMeta; +use sel4_driver_interfaces::timer::{Clock, DefaultTimer}; use sel4_externally_shared::{ExternallySharedRef, ExternallySharedRefExt}; use sel4_logging::{LevelFilter, Logger, LoggerBuilder}; use sel4_microkit::{memory_region_symbol, protection_domain, Handler}; +use sel4_microkit_driver_adapters::block::client::Client as BlockClient; +use sel4_microkit_driver_adapters::net::client::Client as NetClient; +use sel4_microkit_driver_adapters::rtc::client::Client as RtcClient; +use sel4_microkit_driver_adapters::timer::client::Client as TimerClient; use sel4_newlib as _; use sel4_shared_ring_buffer::RingBuffers; use sel4_shared_ring_buffer_block_io::SharedRingBufferBlockIO; @@ -32,19 +41,11 @@ use sel4_shared_ring_buffer_smoltcp::DeviceImpl; use microkit_http_server_example_server_core::run_server; -mod block_client; mod config; mod handler; -mod net_client; -mod rtc_client; -mod timer_client; -use block_client::BlockClient; use config::channels; use handler::HandlerImpl; -use net_client::NetClient; -use rtc_client::RtcClient; -use timer_client::TimerClient; const BLOCK_CACHE_SIZE_IN_BLOCKS: usize = 128; @@ -72,16 +73,27 @@ static LOGGER: Logger = LoggerBuilder::const_default() fn init() -> impl Handler { LOGGER.set().unwrap(); - let rtc_client = RtcClient::new(channels::RTC_DRIVER); - let timer_client = Arc::new(TimerClient::new(channels::TIMER_DRIVER)); - let net_client = NetClient::new(channels::NET_DRIVER); - let block_client = BlockClient::new(channels::BLOCK_DRIVER); + let mut rtc_client = RtcClient::new(channels::RTC_DRIVER); + let mut net_client = NetClient::new(channels::NET_DRIVER); + let mut block_client = BlockClient::new(channels::BLOCK_DRIVER); - let now_unix_time = Duration::from_secs(rtc_client.now().into()); + let timer_client = Arc::new(Mutex::new(DefaultTimer(TimerClient::new( + channels::TIMER_DRIVER, + )))); + + let now_unix_time = Duration::from_secs( + rtc_client + .datetime() + .unwrap() + .and_utc() + .timestamp() + .try_into() + .unwrap(), + ); let now_fn = { - let timer_client = timer_client.clone(); - move || Instant::ZERO + Duration::from_micros(timer_client.now()) + let timer_client: Arc<_> = timer_client.clone(); + move || Instant::ZERO + timer_client.lock().get_time().unwrap() }; let notify_net: fn() = || channels::NET_DRIVER.notify(); @@ -120,21 +132,28 @@ fn init() -> impl Handler { ), 16, 2048, - 1500, + { + let mut caps = DeviceCapabilities::default(); + caps.max_transmission_unit = 1500; + caps + }, ) .unwrap() }; let net_config = { assert_eq!(net_device.capabilities().medium, Medium::Ethernet); - let mac_address = EthernetAddress(net_client.get_mac_address().0); + let mac_address = EthernetAddress(net_client.get_mac_address().unwrap().0); let hardware_addr = HardwareAddress::Ethernet(mac_address); let mut this = Config::new(hardware_addr); this.random_seed = 0; this }; - let num_blocks = block_client.get_num_blocks(); + let block_size = block_client.get_block_size().unwrap(); + assert_eq!(block_size, BlockSize512::BLOCK_SIZE.bytes()); + + let num_blocks = block_client.get_num_blocks().unwrap(); let shared_block_io = { let dma_region = unsafe { diff --git a/crates/examples/microkit/http-server/pds/server/src/net_client.rs b/crates/examples/microkit/http-server/pds/server/src/net_client.rs deleted file mode 100644 index 34dd3b950..000000000 --- a/crates/examples/microkit/http-server/pds/server/src/net_client.rs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -use sel4_microkit::MessageInfo; -use sel4_microkit_message::MessageInfoExt as _; - -use microkit_http_server_example_virtio_net_driver_interface_types::*; - -pub struct NetClient { - channel: sel4_microkit::Channel, -} - -impl NetClient { - pub fn new(channel: sel4_microkit::Channel) -> Self { - Self { channel } - } - - pub fn get_mac_address(&self) -> MacAddress { - let req = Request::GetMacAddress; - let resp: GetMacAddressResponse = self - .channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_using_postcard() - .unwrap(); - resp.mac_address - } -} diff --git a/crates/examples/microkit/http-server/pds/server/src/rtc_client.rs b/crates/examples/microkit/http-server/pds/server/src/rtc_client.rs deleted file mode 100644 index 6cff6becc..000000000 --- a/crates/examples/microkit/http-server/pds/server/src/rtc_client.rs +++ /dev/null @@ -1,30 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -use sel4_microkit::MessageInfo; -use sel4_microkit_message::MessageInfoExt as _; - -use microkit_http_server_example_pl031_driver_interface_types::*; - -pub struct RtcClient { - channel: sel4_microkit::Channel, -} - -impl RtcClient { - pub fn new(channel: sel4_microkit::Channel) -> Self { - Self { channel } - } - - pub fn now(&self) -> Seconds { - let req = Request::Now; - let resp: NowResponse = self - .channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_using_postcard() - .unwrap(); - resp.unix_time - } -} diff --git a/crates/examples/microkit/http-server/pds/server/src/timer_client.rs b/crates/examples/microkit/http-server/pds/server/src/timer_client.rs deleted file mode 100644 index 44a22cbdb..000000000 --- a/crates/examples/microkit/http-server/pds/server/src/timer_client.rs +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -use sel4_microkit::MessageInfo; -use sel4_microkit_message::MessageInfoExt as _; - -use microkit_http_server_example_sp804_driver_interface_types::*; - -pub struct TimerClient { - channel: sel4_microkit::Channel, -} - -impl TimerClient { - pub fn new(channel: sel4_microkit::Channel) -> Self { - Self { channel } - } - - pub fn now(&self) -> Microseconds { - let req = Request::Now; - let resp: NowResponse = self - .channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_using_postcard() - .unwrap(); - resp.micros - } - - pub fn set_timeout(&self, relative_micros: Microseconds) { - let req = Request::SetTimeout { relative_micros }; - self.channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_empty() - .unwrap(); - } - - #[allow(dead_code)] - pub fn clear_timeout(&self) { - let req = Request::ClearTimeout; - self.channel - .pp_call(MessageInfo::send_using_postcard(req).unwrap()) - .recv_empty() - .unwrap(); - } -} diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.nix b/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.nix index 1b6ce3d07..4624c2cfb 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.nix @@ -11,8 +11,9 @@ mk { dependencies = { inherit (localCrates) sel4-microkit-message - microkit-http-server-example-sp804-driver-core - microkit-http-server-example-sp804-driver-interface-types + sel4-microkit-driver-adapters + sel4-driver-interfaces + sel4-sp804-driver ; sel4-microkit = localCrates.sel4-microkit // { default-features = false; }; }; diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.toml b/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.toml index cd8a25f79..cf6d13bd4 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/sp804-driver/Cargo.toml @@ -17,7 +17,8 @@ edition = "2021" license = "BSD-2-Clause" [dependencies] -microkit-http-server-example-sp804-driver-core = { path = "core" } -microkit-http-server-example-sp804-driver-interface-types = { path = "interface-types" } +sel4-driver-interfaces = { path = "../../../../../sel4-driver-interfaces" } sel4-microkit = { path = "../../../../../sel4-microkit", default-features = false } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } +sel4-sp804-driver = { path = "../../../../../drivers/sp804" } diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.nix b/crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.nix deleted file mode 100644 index 9c68309ce..000000000 --- a/crates/examples/microkit/http-server/pds/sp804-driver/core/Cargo.nix +++ /dev/null @@ -1,15 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, versions }: - -mk { - package.name = "microkit-http-server-example-sp804-driver-core"; - dependencies = { - inherit (versions) log; - tock-registers = "0.8.1"; - }; -} diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.nix b/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.nix deleted file mode 100644 index 39fc17d03..000000000 --- a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.nix +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, serdeWith }: - -mk { - package.name = "microkit-http-server-example-sp804-driver-interface-types"; - dependencies = { - serde = serdeWith []; - }; -} diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.toml b/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.toml deleted file mode 100644 index 192df3b44..000000000 --- a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# -# -# This file is generated from './Cargo.nix'. You can edit this file directly -# if you are not using this project's Cargo manifest management tools. -# See 'hacking/cargo-manifest-management/README.md' for more information. -# - -[package] -name = "microkit-http-server-example-sp804-driver-interface-types" -version = "0.1.0" -authors = ["Nick Spinale "] -edition = "2021" -license = "BSD-2-Clause" - -[dependencies] -serde = { version = "1.0.147", default-features = false } diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/src/lib.rs b/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/src/lib.rs deleted file mode 100644 index 6e9c62461..000000000 --- a/crates/examples/microkit/http-server/pds/sp804-driver/interface-types/src/lib.rs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use serde::{Deserialize, Serialize}; - -pub type Microseconds = u64; - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - Now, - SetTimeout { relative_micros: Microseconds }, - ClearTimeout, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct NowResponse { - pub micros: Microseconds, -} diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/src/config.rs b/crates/examples/microkit/http-server/pds/sp804-driver/src/config.rs deleted file mode 100644 index da8579126..000000000 --- a/crates/examples/microkit/http-server/pds/sp804-driver/src/config.rs +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -pub mod channels { - use sel4_microkit::Channel; - - pub const DEVICE: Channel = Channel::new(0); - pub const CLIENT: Channel = Channel::new(1); -} - -pub const FREQ: u64 = 1_000_000; diff --git a/crates/examples/microkit/http-server/pds/sp804-driver/src/main.rs b/crates/examples/microkit/http-server/pds/sp804-driver/src/main.rs index 63d467c50..ba4868349 100644 --- a/crates/examples/microkit/http-server/pds/sp804-driver/src/main.rs +++ b/crates/examples/microkit/http-server/pds/sp804-driver/src/main.rs @@ -7,82 +7,23 @@ #![no_std] #![no_main] -use core::time::Duration; +use sel4_driver_interfaces::timer::SingleTimer; +use sel4_microkit::{memory_region_symbol, protection_domain, Channel, Handler}; +use sel4_microkit_driver_adapters::timer::driver::HandlerImpl; +use sel4_sp804_driver::Driver; -use sel4_microkit::{ - memory_region_symbol, protection_domain, Channel, Handler, Infallible, MessageInfo, -}; -use sel4_microkit_message::MessageInfoExt as _; +const DEVICE: Channel = Channel::new(0); +const CLIENT: Channel = Channel::new(1); -use microkit_http_server_example_sp804_driver_core::Driver; -use microkit_http_server_example_sp804_driver_interface_types::*; - -mod config; - -use config::channels; +const FREQ: u64 = 1_000_000; #[protection_domain] -fn init() -> HandlerImpl { +fn init() -> impl Handler { let driver = unsafe { Driver::new( memory_region_symbol!(sp804_mmio_vaddr: *mut ()).as_ptr(), - config::FREQ, + FREQ, ) }; - HandlerImpl { driver } -} - -struct HandlerImpl { - driver: Driver, -} - -impl Handler for HandlerImpl { - type Error = Infallible; - - fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { - match channel { - channels::DEVICE => { - self.driver.handle_interrupt(); - channels::DEVICE.irq_ack().unwrap(); - channels::CLIENT.notify(); - } - _ => { - unreachable!() - } - } - Ok(()) - } - - fn protected( - &mut self, - channel: Channel, - msg_info: MessageInfo, - ) -> Result { - Ok(match channel { - channels::CLIENT => match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::Now => { - let now = self.driver.now(); - MessageInfo::send_using_postcard(NowResponse { - micros: now.as_micros().try_into().unwrap(), - }) - .unwrap() - } - Request::SetTimeout { relative_micros } => { - self.driver - .set_timeout(Duration::from_micros(relative_micros)); - MessageInfo::send_empty() - } - Request::ClearTimeout => { - self.driver.clear_timeout(); - MessageInfo::send_empty() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - }, - _ => { - unreachable!() - } - }) - } + HandlerImpl::new(SingleTimer(driver), DEVICE, CLIENT).unwrap() } diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.nix b/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.nix index c312486d6..068eeb028 100644 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.nix @@ -21,8 +21,10 @@ mk { sel4-shared-ring-buffer sel4-shared-ring-buffer-block-io-types sel4-bounce-buffer-allocator - microkit-http-server-example-virtio-hal-impl - microkit-http-server-example-virtio-blk-driver-interface-types + sel4-virtio-hal-impl + sel4-virtio-blk + sel4-driver-interfaces + sel4-microkit-driver-adapters ; sel4-externally-shared = localCrates.sel4-externally-shared // { features = [ "unstable" ]; }; diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.toml b/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.toml index bb2052530..c7637176f 100644 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/virtio-blk-driver/Cargo.toml @@ -18,17 +18,19 @@ license = "BSD-2-Clause" [dependencies] log = "0.4.17" -microkit-http-server-example-virtio-blk-driver-interface-types = { path = "interface-types" } -microkit-http-server-example-virtio-hal-impl = { path = "../../helpers/virtio-hal-impl" } sel4 = { path = "../../../../../sel4" } sel4-bounce-buffer-allocator = { path = "../../../../../sel4-bounce-buffer-allocator" } +sel4-driver-interfaces = { path = "../../../../../sel4-driver-interfaces" } sel4-externally-shared = { path = "../../../../../sel4-externally-shared", features = ["unstable"] } sel4-immediate-sync-once-cell = { path = "../../../../../sel4-immediate-sync-once-cell" } sel4-logging = { path = "../../../../../sel4-logging" } sel4-microkit = { path = "../../../../../sel4-microkit", default-features = false } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } sel4-shared-ring-buffer = { path = "../../../../../sel4-shared-ring-buffer" } -virtio-drivers = { version = "0.5.0", default-features = false } +sel4-virtio-blk = { path = "../../../../../drivers/virtio/blk" } +sel4-virtio-hal-impl = { path = "../../../../../drivers/virtio/hal-impl" } +virtio-drivers = { version = "0.7.2", default-features = false } [dependencies.sel4-shared-ring-buffer-block-io-types] path = "../../../../../sel4-shared-ring-buffer/block-io/types" diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.nix b/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.nix deleted file mode 100644 index 2ba020fb5..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.nix +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, serdeWith }: - -mk { - package.name = "microkit-http-server-example-virtio-blk-driver-interface-types"; - dependencies = { - serde = serdeWith []; - }; -} diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.toml b/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.toml deleted file mode 100644 index 265855f02..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# -# -# This file is generated from './Cargo.nix'. You can edit this file directly -# if you are not using this project's Cargo manifest management tools. -# See 'hacking/cargo-manifest-management/README.md' for more information. -# - -[package] -name = "microkit-http-server-example-virtio-blk-driver-interface-types" -version = "0.1.0" -authors = ["Nick Spinale "] -edition = "2021" -license = "BSD-2-Clause" - -[dependencies] -serde = { version = "1.0.147", default-features = false } diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/src/lib.rs b/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/src/lib.rs deleted file mode 100644 index 7f835b388..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/interface-types/src/lib.rs +++ /dev/null @@ -1,19 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - GetNumBlocks, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetNumBlocksResponse { - pub num_blocks: u64, -} diff --git a/crates/examples/microkit/http-server/pds/virtio-blk-driver/src/main.rs b/crates/examples/microkit/http-server/pds/virtio-blk-driver/src/main.rs index 3e8a1661c..649aae1f2 100644 --- a/crates/examples/microkit/http-server/pds/virtio-blk-driver/src/main.rs +++ b/crates/examples/microkit/http-server/pds/virtio-blk-driver/src/main.rs @@ -26,14 +26,13 @@ use sel4_externally_shared::{ExternallySharedRef, ExternallySharedRefExt}; use sel4_microkit::{ memory_region_symbol, protection_domain, var, Channel, Handler, Infallible, MessageInfo, }; -use sel4_microkit_message::MessageInfoExt as _; +use sel4_microkit_driver_adapters::block::driver::handle_client_request; use sel4_shared_ring_buffer::{roles::Use, RingBuffers}; use sel4_shared_ring_buffer_block_io_types::{ BlockIORequest, BlockIORequestStatus, BlockIORequestType, }; - -use microkit_http_server_example_virtio_blk_driver_interface_types::*; -use microkit_http_server_example_virtio_hal_impl::HalImpl; +use sel4_virtio_blk::GetBlockDeviceLayoutWrapper; +use sel4_virtio_hal_impl::HalImpl; mod config; @@ -126,7 +125,7 @@ impl Handler for HandlerImpl { unsafe { let pending_entry = &mut *pending_entry; self.dev - .complete_read_block( + .complete_read_blocks( token, &pending_entry.virtio_req, buf_ptr.as_mut(), @@ -172,7 +171,7 @@ impl Handler for HandlerImpl { let token = unsafe { let pending_entry = &mut *pending_entry; self.dev - .read_block_nb( + .read_blocks_nb( pending_entry .client_req .start_block_idx() @@ -207,20 +206,14 @@ impl Handler for HandlerImpl { channel: Channel, msg_info: MessageInfo, ) -> Result { - Ok(match channel { - channels::CLIENT => match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::GetNumBlocks => { - let num_blocks = self.dev.capacity(); - MessageInfo::send_using_postcard(GetNumBlocksResponse { num_blocks }) - .unwrap() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - }, + match channel { + channels::CLIENT => Ok(handle_client_request( + &mut GetBlockDeviceLayoutWrapper(&self.dev), + msg_info, + )), _ => { unreachable!() } - }) + } } } diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.nix b/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.nix index e0e22ad4a..f0adafde3 100644 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.nix +++ b/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.nix @@ -15,13 +15,14 @@ mk { inherit (localCrates) sel4-microkit-message + sel4-microkit-driver-adapters sel4 sel4-logging sel4-immediate-sync-once-cell sel4-shared-ring-buffer sel4-bounce-buffer-allocator - microkit-http-server-example-virtio-hal-impl - microkit-http-server-example-virtio-net-driver-interface-types + sel4-virtio-hal-impl + sel4-virtio-net ; sel4-externally-shared = localCrates.sel4-externally-shared // { features = [ "unstable" ]; }; diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.toml b/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.toml index 0ca15c7f4..78c4ba847 100644 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.toml +++ b/crates/examples/microkit/http-server/pds/virtio-net-driver/Cargo.toml @@ -18,14 +18,15 @@ license = "BSD-2-Clause" [dependencies] log = "0.4.17" -microkit-http-server-example-virtio-hal-impl = { path = "../../helpers/virtio-hal-impl" } -microkit-http-server-example-virtio-net-driver-interface-types = { path = "interface-types" } sel4 = { path = "../../../../../sel4" } sel4-bounce-buffer-allocator = { path = "../../../../../sel4-bounce-buffer-allocator" } sel4-externally-shared = { path = "../../../../../sel4-externally-shared", features = ["unstable"] } sel4-immediate-sync-once-cell = { path = "../../../../../sel4-immediate-sync-once-cell" } sel4-logging = { path = "../../../../../sel4-logging" } sel4-microkit = { path = "../../../../../sel4-microkit", default-features = false } +sel4-microkit-driver-adapters = { path = "../../../../../sel4-microkit/driver-adapters" } sel4-microkit-message = { path = "../../../../../sel4-microkit/message" } sel4-shared-ring-buffer = { path = "../../../../../sel4-shared-ring-buffer" } -virtio-drivers = { version = "0.5.0", default-features = false, features = ["alloc"] } +sel4-virtio-hal-impl = { path = "../../../../../drivers/virtio/hal-impl" } +sel4-virtio-net = { path = "../../../../../drivers/virtio/net" } +virtio-drivers = { version = "0.7.2", default-features = false, features = ["alloc"] } diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.nix b/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.nix deleted file mode 100644 index f1eccf4fb..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.nix +++ /dev/null @@ -1,14 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, localCrates, serdeWith }: - -mk { - package.name = "microkit-http-server-example-virtio-net-driver-interface-types"; - dependencies = { - serde = serdeWith []; - }; -} diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.toml b/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.toml deleted file mode 100644 index 1c7696b08..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# -# SPDX-License-Identifier: BSD-2-Clause -# -# -# This file is generated from './Cargo.nix'. You can edit this file directly -# if you are not using this project's Cargo manifest management tools. -# See 'hacking/cargo-manifest-management/README.md' for more information. -# - -[package] -name = "microkit-http-server-example-virtio-net-driver-interface-types" -version = "0.1.0" -authors = ["Nick Spinale "] -edition = "2021" -license = "BSD-2-Clause" - -[dependencies] -serde = { version = "1.0.147", default-features = false } diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/src/lib.rs b/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/src/lib.rs deleted file mode 100644 index b98ccd9e2..000000000 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/interface-types/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Serialize, Deserialize)] -pub struct MacAddress(pub [u8; 6]); - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - GetMacAddress, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetMacAddressResponse { - pub mac_address: MacAddress, -} diff --git a/crates/examples/microkit/http-server/pds/virtio-net-driver/src/main.rs b/crates/examples/microkit/http-server/pds/virtio-net-driver/src/main.rs index 9a85c7227..ee60d4b28 100644 --- a/crates/examples/microkit/http-server/pds/virtio-net-driver/src/main.rs +++ b/crates/examples/microkit/http-server/pds/virtio-net-driver/src/main.rs @@ -18,14 +18,11 @@ use virtio_drivers::{ }; use sel4_externally_shared::{ExternallySharedRef, ExternallySharedRefExt}; -use sel4_microkit::{ - memory_region_symbol, protection_domain, var, Channel, Handler, Infallible, MessageInfo, -}; -use sel4_microkit_message::MessageInfoExt as _; +use sel4_microkit::{memory_region_symbol, protection_domain, var}; +use sel4_microkit_driver_adapters::net::driver::HandlerImpl; use sel4_shared_ring_buffer::{roles::Use, RingBuffers}; - -use microkit_http_server_example_virtio_hal_impl::HalImpl; -use microkit_http_server_example_virtio_net_driver_interface_types::*; +use sel4_virtio_hal_impl::HalImpl; +use sel4_virtio_net::DeviceWrapper; mod config; @@ -37,7 +34,7 @@ const NET_BUFFER_LEN: usize = 2048; #[protection_domain( heap_size = 512 * 1024, )] -fn init() -> HandlerImpl { +fn init() -> HandlerImpl> { HalImpl::init( config::VIRTIO_NET_DRIVER_DMA_SIZE, *var!(virtio_net_driver_dma_vaddr: usize = 0), @@ -80,112 +77,12 @@ fn init() -> HandlerImpl { dev.ack_interrupt(); channels::DEVICE.irq_ack().unwrap(); - HandlerImpl { - dev, + HandlerImpl::new( + DeviceWrapper::new(dev), client_region, rx_ring_buffers, tx_ring_buffers, - } -} - -struct HandlerImpl { - dev: VirtIONet, - client_region: ExternallySharedRef<'static, [u8]>, - rx_ring_buffers: RingBuffers<'static, Use, fn()>, - tx_ring_buffers: RingBuffers<'static, Use, fn()>, -} - -impl Handler for HandlerImpl { - type Error = Infallible; - - fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { - match channel { - channels::DEVICE | channels::CLIENT => { - let mut notify_rx = false; - - while self.dev.can_recv() && !self.rx_ring_buffers.free_mut().is_empty().unwrap() { - let rx_buf = self.dev.receive().unwrap(); - let desc = self.rx_ring_buffers.free_mut().dequeue().unwrap().unwrap(); - let desc_len = usize::try_from(desc.len()).unwrap(); - assert!(desc_len >= rx_buf.packet_len()); - let buf_range = { - let start = desc.encoded_addr(); - start..start + rx_buf.packet_len() - }; - self.client_region - .as_mut_ptr() - .index(buf_range) - .copy_from_slice(rx_buf.packet()); - self.dev.recycle_rx_buffer(rx_buf).unwrap(); - self.rx_ring_buffers - .used_mut() - .enqueue_and_commit(desc) - .unwrap() - .unwrap(); - notify_rx = true; - } - - if notify_rx { - self.rx_ring_buffers.notify(); - } - - let mut notify_tx = false; - - while !self.tx_ring_buffers.free_mut().is_empty().unwrap() && self.dev.can_send() { - let desc = self.tx_ring_buffers.free_mut().dequeue().unwrap().unwrap(); - let buf_range = { - let start = desc.encoded_addr(); - start..start + usize::try_from(desc.len()).unwrap() - }; - let mut tx_buf = self.dev.new_tx_buffer(buf_range.len()); - self.client_region - .as_ptr() - .index(buf_range) - .copy_into_slice(tx_buf.packet_mut()); - self.dev.send(tx_buf).unwrap(); - self.tx_ring_buffers - .used_mut() - .enqueue_and_commit(desc) - .unwrap() - .unwrap(); - notify_tx = true; - } - - if notify_tx { - self.tx_ring_buffers.notify(); - } - - self.dev.ack_interrupt(); - channels::DEVICE.irq_ack().unwrap(); - } - _ => { - unreachable!() - } - } - Ok(()) - } - - fn protected( - &mut self, - channel: Channel, - msg_info: MessageInfo, - ) -> Result { - Ok(match channel { - channels::CLIENT => match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::GetMacAddress => { - let mac_address = self.dev.mac_address(); - MessageInfo::send_using_postcard(GetMacAddressResponse { - mac_address: MacAddress(mac_address), - }) - .unwrap() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - }, - _ => { - unreachable!() - } - }) - } + channels::DEVICE, + channels::CLIENT, + ) } diff --git a/crates/sel4-async/io/Cargo.nix b/crates/sel4-async/io/Cargo.nix index 3af5bb001..24501a35e 100644 --- a/crates/sel4-async/io/Cargo.nix +++ b/crates/sel4-async/io/Cargo.nix @@ -12,4 +12,7 @@ mk rec { }); package.name = "sel4-async-io"; package.license = "MIT OR Apache-2.0"; + dependencies = { + inherit (versions) embedded-io-async; + }; } diff --git a/crates/sel4-async/io/Cargo.toml b/crates/sel4-async/io/Cargo.toml index bf0818008..4370cadc3 100644 --- a/crates/sel4-async/io/Cargo.toml +++ b/crates/sel4-async/io/Cargo.toml @@ -15,3 +15,6 @@ version = "0.1.0" authors = ["Nick Spinale "] edition = "2021" license = "MIT OR Apache-2.0" + +[dependencies] +embedded-io-async = "0.6.1" diff --git a/crates/sel4-async/io/src/lib.rs b/crates/sel4-async/io/src/lib.rs index acf2a8b74..ea6938034 100644 --- a/crates/sel4-async/io/src/lib.rs +++ b/crates/sel4-async/io/src/lib.rs @@ -9,14 +9,13 @@ #![no_std] -use core::fmt; -use core::future::poll_fn; -use core::pin::Pin; +use core::future::{poll_fn, Future}; +use core::pin::{pin, Pin}; use core::task::{Context, Poll}; -pub trait ErrorType { - type Error: fmt::Debug; -} +use embedded_io_async as eio; + +pub use embedded_io_async::{Error, ErrorKind, ErrorType}; pub trait Read: ErrorType { fn poll_read( @@ -24,95 +23,158 @@ pub trait Read: ErrorType { cx: &mut Context<'_>, buf: &mut [u8], ) -> Poll>; +} - // // // +pub trait Write: ErrorType { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll>; - #[allow(async_fn_in_trait)] - async fn read(&mut self, buf: &mut [u8]) -> Result - where - Self: Unpin, - { - let mut pin = Pin::new(self); - poll_fn(move |cx| pin.as_mut().poll_read(cx, buf)).await + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + Poll::Ready(Ok(())) } +} - #[allow(async_fn_in_trait)] - async fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), ReadExactError> - where - Self: Unpin, - { - while !buf.is_empty() { - match self.read(buf).await { - Ok(0) => break, - Ok(n) => buf = &mut buf[n..], - Err(e) => return Err(ReadExactError::Other(e)), - } - } - if buf.is_empty() { - Ok(()) - } else { - Err(ReadExactError::UnexpectedEof) - } +impl Read for &mut T { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + T::poll_read(Pin::new(*Pin::into_inner(self)), cx, buf) } } -pub trait Write: ErrorType { +impl Write for &mut T { fn poll_write( self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8], - ) -> Poll>; + ) -> Poll> { + T::poll_write(Pin::new(*Pin::into_inner(self)), cx, buf) + } - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + T::poll_flush(Pin::new(*Pin::into_inner(self)), cx) + } +} - // // // +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct EmbeddedIOAsyncAdapter(pub T); - #[allow(async_fn_in_trait)] - async fn write(&mut self, buf: &[u8]) -> Result - where - Self: Unpin, - { - let mut pin = Pin::new(self); - poll_fn(|cx| pin.as_mut().poll_write(cx, buf)).await +impl ErrorType for EmbeddedIOAsyncAdapter { + type Error = T::Error; +} + +impl eio::Read for EmbeddedIOAsyncAdapter +where + T: Read + Unpin, +{ + async fn read(&mut self, buf: &mut [u8]) -> Result { + poll_fn(|cx| Pin::new(&mut self.0).poll_read(cx, buf)).await } +} - #[allow(async_fn_in_trait)] - async fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> - where - Self: Unpin, - { - let mut buf = buf; - while !buf.is_empty() { - match self.write(buf).await { - Ok(0) => panic!("write() returned Ok(0)"), - Ok(n) => buf = &buf[n..], - Err(e) => return Err(e), - } - } - Ok(()) +impl eio::Write for EmbeddedIOAsyncAdapter +where + T: Write + Unpin, +{ + async fn write(&mut self, buf: &[u8]) -> Result { + poll_fn(|cx| Pin::new(&mut self.0).poll_write(cx, buf)).await + } + + async fn flush(&mut self) -> Result<(), Self::Error> { + poll_fn(|cx| Pin::new(&mut self.0).poll_flush(cx)).await + } +} + +pub trait ReadCancelSafe: eio::Read {} +pub trait FlushCancelSafe: eio::Write {} +pub trait WriteCancelSafe: FlushCancelSafe {} + +impl ReadCancelSafe for EmbeddedIOAsyncAdapter {} +impl FlushCancelSafe for EmbeddedIOAsyncAdapter {} +impl WriteCancelSafe for EmbeddedIOAsyncAdapter {} + +impl Read for EmbeddedIOAsyncAdapter +where + T: eio::Read + ReadCancelSafe + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + pin!(self.0.read(buf)).poll(cx) + } +} + +impl Write for EmbeddedIOAsyncAdapter +where + T: eio::Write + WriteCancelSafe + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + pin!(self.0.write(buf)).poll(cx) } - #[allow(async_fn_in_trait)] - async fn flush(&mut self) -> Result<(), Self::Error> - where - Self: Unpin, - { - let mut pin = Pin::new(self); - poll_fn(|cx| pin.as_mut().poll_flush(cx)).await + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + pin!(self.0.flush()).poll(cx) } } -/// Error returned by [`Read::read_exact`] -#[derive(Debug, Copy, Clone, Eq, PartialEq)] -pub enum ReadExactError { - /// An EOF error was encountered before reading the exact amount of requested bytes. - UnexpectedEof, - /// Error returned by the inner Read. - Other(E), +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +pub struct EmbeddedIOAsyncAdapterUsingReady(pub T); + +impl ErrorType for EmbeddedIOAsyncAdapterUsingReady { + type Error = T::Error; } -impl From for ReadExactError { - fn from(err: E) -> Self { - Self::Other(err) +impl Read for EmbeddedIOAsyncAdapterUsingReady +where + T: eio::Read + eio::ReadReady + Unpin, +{ + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + if self.0.read_ready()? { + match pin!(self.0.read(buf)).poll(cx) { + Poll::Ready(r) => Poll::Ready(r), + Poll::Pending => unreachable!(), + } + } else { + Poll::Pending + } + } +} + +impl Write for EmbeddedIOAsyncAdapterUsingReady +where + T: eio::Write + eio::WriteReady + FlushCancelSafe + Unpin, +{ + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + if self.0.write_ready()? { + match pin!(self.0.write(buf)).poll(cx) { + Poll::Ready(r) => Poll::Ready(r), + Poll::Pending => unreachable!(), + } + } else { + Poll::Pending + } + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + pin!(self.0.flush()).poll(cx) } } diff --git a/crates/sel4-async/network/rustls/Cargo.nix b/crates/sel4-async/network/rustls/Cargo.nix index 3721a241b..73476f90a 100644 --- a/crates/sel4-async/network/rustls/Cargo.nix +++ b/crates/sel4-async/network/rustls/Cargo.nix @@ -16,7 +16,7 @@ mk rec { inherit (localCrates) sel4-async-io ; - inherit (versions) log; + inherit (versions) log embedded-io-async; rustls = rustlsWith [] // (localCrates.rustls or {}); }; } diff --git a/crates/sel4-async/network/rustls/Cargo.toml b/crates/sel4-async/network/rustls/Cargo.toml index 5bc8bb4b1..d8fefe268 100644 --- a/crates/sel4-async/network/rustls/Cargo.toml +++ b/crates/sel4-async/network/rustls/Cargo.toml @@ -17,6 +17,7 @@ edition = "2021" license = "Apache-2.0 OR ISC OR MIT" [dependencies] +embedded-io-async = "0.6.1" log = "0.4.17" rustls = { version = "0.23.5", default-features = false, features = ["logging", "ring", "tls12"] } sel4-async-io = { path = "../../io" } diff --git a/crates/sel4-async/network/rustls/src/conn.rs b/crates/sel4-async/network/rustls/src/conn.rs index cca2a3bb1..295ff4364 100644 --- a/crates/sel4-async/network/rustls/src/conn.rs +++ b/crates/sel4-async/network/rustls/src/conn.rs @@ -23,7 +23,7 @@ use rustls::unbuffered::{ }; use rustls::{unbuffered::UnbufferedConnectionCommon, ClientConfig, ServerConfig, SideData}; -use sel4_async_io::{Read, Write}; +use sel4_async_io::{ErrorType, Read, Write}; use crate::{ utils::{poll_read, poll_write, try_or_resize_and_retry, Buffer, WriteCursor}, @@ -288,9 +288,9 @@ impl TlsStream { } } -impl sel4_async_io::ErrorType for TlsStream +impl ErrorType for TlsStream where - IO: sel4_async_io::ErrorType, + IO: ErrorType, { type Error = Error; } diff --git a/crates/sel4-async/network/rustls/src/error.rs b/crates/sel4-async/network/rustls/src/error.rs index cb0a6af51..f491eb5a3 100644 --- a/crates/sel4-async/network/rustls/src/error.rs +++ b/crates/sel4-async/network/rustls/src/error.rs @@ -4,9 +4,13 @@ // SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT // +use core::fmt::Debug; + use rustls::unbuffered::{EncodeError, EncryptError}; use rustls::Error as TlsError; +use sel4_async_io::{Error as AsyncIOError, ErrorKind}; + #[derive(Debug)] pub enum Error { TransitError(E), @@ -33,3 +37,9 @@ impl From for Error { Self::EncryptError(err) } } + +impl AsyncIOError for Error { + fn kind(&self) -> ErrorKind { + ErrorKind::Other + } +} diff --git a/crates/sel4-async/network/src/lib.rs b/crates/sel4-async/network/src/lib.rs index ded7b52db..2c3b2b1fb 100644 --- a/crates/sel4-async/network/src/lib.rs +++ b/crates/sel4-async/network/src/lib.rs @@ -29,7 +29,7 @@ use smoltcp::{ wire::{DnsQueryType, IpAddress, IpCidr, IpEndpoint, IpListenEndpoint, Ipv4Address, Ipv4Cidr}, }; -use sel4_async_io::{Read, Write}; +use sel4_async_io::{Error as AsyncIOError, ErrorKind, ErrorType, Read, Write}; pub(crate) const DEFAULT_KEEP_ALIVE_INTERVAL: u64 = 75000; pub(crate) const DEFAULT_TCP_SOCKET_BUFFER_SIZE: usize = 65535; @@ -82,6 +82,12 @@ pub enum TcpSocketError { ConnectionResetDuringConnect, } +impl AsyncIOError for TcpSocketError { + fn kind(&self) -> ErrorKind { + ErrorKind::Other + } +} + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum DnsError { StartQueryError(dns::StartQueryError), @@ -290,7 +296,7 @@ impl Socket> { } } -impl sel4_async_io::ErrorType for Socket> { +impl ErrorType for Socket> { type Error = TcpSocketError; } diff --git a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.nix b/crates/sel4-driver-interfaces/Cargo.nix similarity index 50% rename from crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.nix rename to crates/sel4-driver-interfaces/Cargo.nix index 2f76b762e..a94f3b3d0 100644 --- a/crates/examples/microkit/banscii/pds/pl011-driver/interface-types/Cargo.nix +++ b/crates/sel4-driver-interfaces/Cargo.nix @@ -7,8 +7,9 @@ { mk, versions, serdeWith }: mk { - package.name = "banscii-pl011-driver-interface-types"; + package.name = "sel4-driver-interfaces"; dependencies = { - serde = serdeWith []; + inherit (versions) embedded-hal-nb rtcc heapless lock_api; + serde = serdeWith [ "derive" ]; }; } diff --git a/crates/sel4-driver-interfaces/Cargo.toml b/crates/sel4-driver-interfaces/Cargo.toml new file mode 100644 index 000000000..4e3013bf5 --- /dev/null +++ b/crates/sel4-driver-interfaces/Cargo.toml @@ -0,0 +1,24 @@ +# +# Copyright 2023, Colias Group, LLC +# +# SPDX-License-Identifier: BSD-2-Clause +# +# +# This file is generated from './Cargo.nix'. You can edit this file directly +# if you are not using this project's Cargo manifest management tools. +# See 'hacking/cargo-manifest-management/README.md' for more information. +# + +[package] +name = "sel4-driver-interfaces" +version = "0.1.0" +authors = ["Nick Spinale "] +edition = "2021" +license = "BSD-2-Clause" + +[dependencies] +embedded-hal-nb = "1.0" +heapless = "0.7.16" +lock_api = "0.4.12" +rtcc = "0.3.2" +serde = { version = "1.0.147", default-features = false, features = ["derive"] } diff --git a/crates/sel4-driver-interfaces/src/block.rs b/crates/sel4-driver-interfaces/src/block.rs new file mode 100644 index 000000000..ffb3c27f0 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/block.rs @@ -0,0 +1,53 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::cell::RefCell; +use core::fmt; +use core::ops::Deref; + +use lock_api::{Mutex, RawMutex}; +use serde::{Deserialize, Serialize}; + +use crate::{WrappedMutex, WrappedRefCell, WrappedRefCellError}; + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub struct MacAddress(pub [u8; 6]); + +pub trait GetBlockDeviceLayout { + type Error: fmt::Debug; + + fn get_block_size(&mut self) -> Result; + + fn get_num_blocks(&mut self) -> Result; +} + +impl>, U: GetBlockDeviceLayout> GetBlockDeviceLayout + for &WrappedRefCell +{ + type Error = WrappedRefCellError; + + fn get_block_size(&mut self) -> Result { + self.with_mut(|this| this.get_block_size()) + } + + fn get_num_blocks(&mut self) -> Result { + self.with_mut(|this| this.get_num_blocks()) + } +} + +impl>, U: GetBlockDeviceLayout> GetBlockDeviceLayout + for &WrappedMutex +{ + type Error = U::Error; + + fn get_block_size(&mut self) -> Result { + self.with_mut(|this| this.get_block_size()) + } + + fn get_num_blocks(&mut self) -> Result { + self.with_mut(|this| this.get_num_blocks()) + } +} diff --git a/crates/sel4-driver-interfaces/src/lib.rs b/crates/sel4-driver-interfaces/src/lib.rs new file mode 100644 index 000000000..a9c442d13 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/lib.rs @@ -0,0 +1,86 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +#![no_std] + +use core::cell::{RefCell, RefMut}; +use core::fmt; +use core::ops::{Deref, DerefMut}; + +use lock_api::{Mutex, RawMutex}; + +pub mod block; +pub mod net; +pub mod rtc; +pub mod serial; +pub mod timer; + +pub trait HandleInterrupt { + fn handle_interrupt(&mut self); +} + +// // // + +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Default)] +pub struct WrappedRefCell(pub T); + +impl WrappedRefCell { + pub(crate) fn try_borrow_mut(&self) -> Result, WrappedRefCellError> + where + T: Deref>, + { + self.0 + .deref() + .try_borrow_mut() + .map_err(|_| WrappedRefCellError::Contention) + } + + pub(crate) fn with_mut( + &self, + f: impl FnOnce(&mut U) -> Result, + ) -> Result> + where + T: Deref>, + { + Ok(f(self.try_borrow_mut()?.deref_mut())?) + } +} + +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash)] +pub enum WrappedRefCellError { + Contention, + Other(E), +} + +impl From for WrappedRefCellError { + fn from(err: E) -> Self { + Self::Other(err) + } +} + +impl fmt::Display for WrappedRefCellError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::Contention => write!(f, "contention"), + Self::Other(err) => err.fmt(f), + } + } +} + +#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Default)] +pub struct WrappedMutex(pub T); + +impl WrappedMutex { + pub(crate) fn with_mut( + &self, + f: impl FnOnce(&mut U) -> Result, + ) -> Result + where + T: Deref>, + { + f(self.0.lock().deref_mut()) + } +} diff --git a/crates/sel4-driver-interfaces/src/net.rs b/crates/sel4-driver-interfaces/src/net.rs new file mode 100644 index 000000000..736407826 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/net.rs @@ -0,0 +1,41 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::cell::RefCell; +use core::fmt; +use core::ops::Deref; + +use lock_api::{Mutex, RawMutex}; +use serde::{Deserialize, Serialize}; + +use crate::{WrappedMutex, WrappedRefCell, WrappedRefCellError}; + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)] +pub struct MacAddress(pub [u8; 6]); + +pub trait GetNetDeviceMeta { + type Error: fmt::Debug; + + fn get_mac_address(&mut self) -> Result; +} + +impl>, U: GetNetDeviceMeta> GetNetDeviceMeta for &WrappedRefCell { + type Error = WrappedRefCellError; + + fn get_mac_address(&mut self) -> Result { + self.with_mut(|this| this.get_mac_address()) + } +} + +impl>, U: GetNetDeviceMeta> GetNetDeviceMeta + for &WrappedMutex +{ + type Error = U::Error; + + fn get_mac_address(&mut self) -> Result { + self.with_mut(|this| this.get_mac_address()) + } +} diff --git a/crates/sel4-driver-interfaces/src/rtc.rs b/crates/sel4-driver-interfaces/src/rtc.rs new file mode 100644 index 000000000..525a61ca2 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/rtc.rs @@ -0,0 +1,40 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::cell::RefCell; +use core::ops::Deref; + +use lock_api::{Mutex, RawMutex}; + +use crate::{WrappedMutex, WrappedRefCell, WrappedRefCellError}; + +pub use rtcc::{DateTime, DateTimeAccess, Datelike, NaiveDate, NaiveDateTime, NaiveTime, Timelike}; + +impl>, U: DateTimeAccess> DateTimeAccess for &WrappedRefCell { + type Error = WrappedRefCellError; + + fn datetime(&mut self) -> Result { + self.with_mut(|this| this.datetime()) + } + + fn set_datetime(&mut self, datetime: &NaiveDateTime) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_datetime(datetime)) + } +} + +impl>, U: DateTimeAccess> DateTimeAccess + for &WrappedMutex +{ + type Error = U::Error; + + fn datetime(&mut self) -> Result { + self.with_mut(|this| this.datetime()) + } + + fn set_datetime(&mut self, datetime: &NaiveDateTime) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_datetime(datetime)) + } +} diff --git a/crates/sel4-driver-interfaces/src/serial/mod.rs b/crates/sel4-driver-interfaces/src/serial/mod.rs new file mode 100644 index 000000000..6ac446c08 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/serial/mod.rs @@ -0,0 +1,80 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::cell::RefCell; +use core::ops::Deref; + +use lock_api::{Mutex, RawMutex}; + +use crate::{WrappedMutex, WrappedRefCell, WrappedRefCellError}; + +pub use embedded_hal_nb::nb; +pub use embedded_hal_nb::serial::{Error, ErrorKind, ErrorType, Read, Write}; + +mod write_buffered; + +pub use write_buffered::WriteBuffered; + +// // // + +impl Error for WrappedRefCellError { + fn kind(&self) -> ErrorKind { + match self { + Self::Contention => ErrorKind::Other, + Self::Other(err) => err.kind(), + } + } +} + +impl>, U: ErrorType> ErrorType for &WrappedRefCell { + type Error = WrappedRefCellError; +} + +impl>, U: Read> Read for &WrappedRefCell { + fn read(&mut self) -> nb::Result { + self.try_borrow_mut()? + .read() + .map_err(|err| err.map(WrappedRefCellError::Other)) + } +} + +impl>, U: Write> Write for &WrappedRefCell { + fn write(&mut self, word: Word) -> nb::Result<(), Self::Error> { + self.try_borrow_mut()? + .write(word) + .map_err(|err| err.map(WrappedRefCellError::Other)) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.try_borrow_mut()? + .flush() + .map_err(|err| err.map(WrappedRefCellError::Other)) + } +} + +impl>, U: ErrorType> ErrorType for &WrappedMutex { + type Error = U::Error; +} + +impl>, U: Read> Read + for &WrappedMutex +{ + fn read(&mut self) -> nb::Result { + self.0.lock().read() + } +} + +impl>, U: Write> Write + for &WrappedMutex +{ + fn write(&mut self, word: Word) -> nb::Result<(), Self::Error> { + self.0.lock().write(word) + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.0.lock().flush() + } +} diff --git a/crates/sel4-driver-interfaces/src/serial/write_buffered.rs b/crates/sel4-driver-interfaces/src/serial/write_buffered.rs new file mode 100644 index 000000000..63a168df6 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/serial/write_buffered.rs @@ -0,0 +1,86 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use embedded_hal_nb::nb; +use embedded_hal_nb::serial; +use heapless::Deque; + +#[derive(Debug, Clone)] +pub struct WriteBuffered { + unbuffered: T, + write_buffer: Deque, +} + +impl WriteBuffered { + pub fn new(unbuffered: T) -> Self { + Self { + unbuffered, + write_buffer: Deque::new(), + } + } + + fn enqueue(&mut self, v: u8) -> nb::Result<(), E> { + match self.write_buffer.push_back(v) { + Ok(()) => Ok(()), + Err(_) => Err(nb::Error::WouldBlock), + } + } + + fn enqueue_if_would_block(&mut self, err: nb::Error, v: u8) -> nb::Result<(), E> { + match err { + err @ nb::Error::Other(_) => Err(err), + nb::Error::WouldBlock => self.enqueue(v), + } + } +} + +impl, const WRITE_BUF_SIZE: usize> WriteBuffered { + fn write_entire_buffer(&mut self) -> nb::Result<(), ::Error> { + loop { + if let Some(v) = self.write_buffer.front() { + if let err @ Err(_) = self.unbuffered.write(*v) { + break err; + } + } else { + break Ok(()); + } + self.write_buffer.pop_front().unwrap(); + } + } +} + +impl serial::ErrorType + for WriteBuffered +{ + type Error = T::Error; +} + +impl serial::Read + for WriteBuffered +{ + fn read(&mut self) -> nb::Result { + self.unbuffered.read() + } +} + +impl serial::Write + for WriteBuffered +{ + fn write(&mut self, v: u8) -> nb::Result<(), Self::Error> { + match self.write_entire_buffer() { + Err(err) => self.enqueue_if_would_block(err, v), + Ok(()) => match self.unbuffered.write(v) { + Err(err) => self.enqueue_if_would_block(err, v), + Ok(()) => Ok(()), + }, + } + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + self.write_entire_buffer()?; + self.unbuffered.flush() + } +} diff --git a/crates/sel4-driver-interfaces/src/timer.rs b/crates/sel4-driver-interfaces/src/timer.rs new file mode 100644 index 000000000..d649c2ce4 --- /dev/null +++ b/crates/sel4-driver-interfaces/src/timer.rs @@ -0,0 +1,225 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::cell::RefCell; +use core::fmt; +use core::ops::Deref; +use core::time::Duration; + +use lock_api::{Mutex, RawMutex}; + +use crate::{HandleInterrupt, WrappedMutex, WrappedRefCell, WrappedRefCellError}; + +pub trait ErrorType { + type Error: fmt::Debug; +} + +pub trait Clock: ErrorType { + fn get_time(&mut self) -> Result; +} + +pub trait Timers: Clock { + type TimerLayout; + + type Timer; + + fn timer_layout(&mut self) -> Result; + + fn set_timeout_on(&mut self, timer: Self::Timer, relative: Duration) + -> Result<(), Self::Error>; + + fn clear_timeout_on(&mut self, timer: Self::Timer) -> Result<(), Self::Error>; +} + +pub trait Timer: Clock { + fn set_timeout(&mut self, relative: Duration) -> Result<(), Self::Error>; + + fn clear_timeout(&mut self) -> Result<(), Self::Error>; +} + +pub struct TrivialTimers(pub T); + +impl ErrorType for TrivialTimers { + type Error = T::Error; +} + +impl Clock for TrivialTimers { + fn get_time(&mut self) -> Result { + self.0.get_time() + } +} + +impl Timers for TrivialTimers { + type TimerLayout = (); + + type Timer = (); + + fn timer_layout(&mut self) -> Result { + Ok(()) + } + + fn set_timeout_on( + &mut self, + _timer: Self::Timer, + relative: Duration, + ) -> Result<(), Self::Error> { + self.0.set_timeout(relative) + } + + fn clear_timeout_on(&mut self, _timer: Self::Timer) -> Result<(), Self::Error> { + self.0.clear_timeout() + } +} + +pub struct DefaultTimer(pub T); + +impl ErrorType for DefaultTimer { + type Error = T::Error; +} + +impl Clock for DefaultTimer { + fn get_time(&mut self) -> Result { + self.0.get_time() + } +} + +impl> Timer for DefaultTimer { + fn set_timeout(&mut self, relative: Duration) -> Result<(), Self::Error> { + self.0.set_timeout_on(Default::default(), relative) + } + + fn clear_timeout(&mut self) -> Result<(), Self::Error> { + self.0.clear_timeout_on(Default::default()) + } +} + +pub struct NumTimers(pub usize); + +pub struct SingleTimer(pub T); + +impl ErrorType for SingleTimer { + type Error = T::Error; +} + +impl Clock for SingleTimer { + fn get_time(&mut self) -> Result { + self.0.get_time() + } +} + +impl Timers for SingleTimer { + type TimerLayout = NumTimers; + + type Timer = usize; + + fn timer_layout(&mut self) -> Result { + Ok(NumTimers(1)) + } + + fn set_timeout_on( + &mut self, + _timer: Self::Timer, + relative: Duration, + ) -> Result<(), Self::Error> { + self.0.set_timeout(relative) + } + + fn clear_timeout_on(&mut self, _timer: Self::Timer) -> Result<(), Self::Error> { + self.0.clear_timeout() + } +} + +impl HandleInterrupt for SingleTimer { + fn handle_interrupt(&mut self) { + self.0.handle_interrupt() + } +} + +// // // + +impl>, U: ErrorType> ErrorType for &WrappedRefCell { + type Error = WrappedRefCellError; +} + +impl>, U: Clock> Clock for &WrappedRefCell { + fn get_time(&mut self) -> Result { + self.with_mut(|this| this.get_time()) + } +} + +impl>, U: Timers> Timers for &WrappedRefCell { + type TimerLayout = U::TimerLayout; + + type Timer = U::Timer; + + fn timer_layout(&mut self) -> Result { + self.with_mut(|this| this.timer_layout()) + } + + fn set_timeout_on( + &mut self, + timer: Self::Timer, + relative: Duration, + ) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_timeout_on(timer, relative)) + } + + fn clear_timeout_on(&mut self, timer: Self::Timer) -> Result<(), Self::Error> { + self.with_mut(|this| this.clear_timeout_on(timer)) + } +} + +impl>, U: Timer> Timer for &WrappedRefCell { + fn set_timeout(&mut self, relative: Duration) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_timeout(relative)) + } + + fn clear_timeout(&mut self) -> Result<(), Self::Error> { + self.with_mut(|this| this.clear_timeout()) + } +} + +impl>, U: ErrorType> ErrorType for &WrappedMutex { + type Error = U::Error; +} + +impl>, U: Clock> Clock for &WrappedMutex { + fn get_time(&mut self) -> Result { + self.with_mut(|this| this.get_time()) + } +} + +impl>, U: Timers> Timers for &WrappedMutex { + type TimerLayout = U::TimerLayout; + + type Timer = U::Timer; + + fn timer_layout(&mut self) -> Result { + self.with_mut(|this| this.timer_layout()) + } + + fn set_timeout_on( + &mut self, + timer: Self::Timer, + relative: Duration, + ) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_timeout_on(timer, relative)) + } + + fn clear_timeout_on(&mut self, timer: Self::Timer) -> Result<(), Self::Error> { + self.with_mut(|this| this.clear_timeout_on(timer)) + } +} + +impl>, U: Timer> Timer for &WrappedMutex { + fn set_timeout(&mut self, relative: Duration) -> Result<(), Self::Error> { + self.with_mut(|this| this.set_timeout(relative)) + } + + fn clear_timeout(&mut self) -> Result<(), Self::Error> { + self.with_mut(|this| this.clear_timeout()) + } +} diff --git a/crates/sel4-hal-adapters/Cargo.nix b/crates/sel4-hal-adapters/Cargo.nix deleted file mode 100644 index 0f9f18613..000000000 --- a/crates/sel4-hal-adapters/Cargo.nix +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright 2023, Colias Group, LLC -# Copyright 2023, Galois, Inc. -# -# SPDX-License-Identifier: BSD-2-Clause -# - -{ mk, versions, localCrates, smoltcpWith, serdeWith, authors }: - -mk { - package.name = "sel4-hal-adapters"; - package.authors = with authors; [ - nspin - "Ben Hamlin " - ]; - dependencies = { - inherit (versions) log; - smoltcp = smoltcpWith [] // { optional = true; }; - serde = serdeWith []; - } // (with localCrates; { - inherit sel4-microkit-message; - sel4-microkit = sel4-microkit // { default-features = false; }; - - # smoltcp-phy deps - sel4-bounce-buffer-allocator = sel4-bounce-buffer-allocator // { optional = true; }; - sel4-externally-shared = sel4-externally-shared // { optional = true; features = ["unstable"]; }; - sel4-shared-ring-buffer = sel4-shared-ring-buffer // { optional = true; }; - }); - features = { - default = ["smoltcp-hal"]; - smoltcp-hal = [ - "smoltcp" - "sel4-shared-ring-buffer" - "sel4-externally-shared" - "sel4-bounce-buffer-allocator" - ]; - }; -} diff --git a/crates/sel4-hal-adapters/src/embedded_hal/mod.rs b/crates/sel4-hal-adapters/src/embedded_hal/mod.rs deleted file mode 100644 index 4505f6a6b..000000000 --- a/crates/sel4-hal-adapters/src/embedded_hal/mod.rs +++ /dev/null @@ -1,246 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// Copyright 2023, Galois, Inc. -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![no_std] - -use num_enum::{IntoPrimitive, TryFromPrimitive}; -use zerocopy::{AsBytes, FromBytes}; -use core::fmt; -use heapless::Deque; - -use embedded_hal::serial; -use embedded_hal::prelude::_embedded_hal_serial_Write; -use sel4cp::{Channel, Handler}; -use sel4cp::message::{MessageInfo, NoMessageValue, StatusMessageLabel}; -use sel4cp::message::MessageInfoRecvError; - -/// Handle messages using an implementor of [serial::Read] and [serial::Write]. -#[derive(Clone, Debug)] -pub struct SerialHandler { - /// Device implementing [serial::Read] and [serial::Write]. - device: Device, - /// Channel for this component. - serial: Channel, - /// Channel for client component. - client: Channel, - /// Read buffer. - buffer: Deque, - /// Whether to notify client. - notify: bool, -} - -impl SerialHandler -where - Device: serial::Read + serial::Write + IrqDevice -{ - pub fn new(device: Device, serial: Channel, client: Channel) -> Self { - Self { - device, - serial, - client, - buffer: Deque::new(), - notify: true, - } - } -} - -pub trait IrqDevice { - fn handle_irq(&self); -} - -#[non_exhaustive] -#[derive(Clone, Debug)] -pub enum SerialHandlerError -where - Device: serial::Read + serial::Write, - >::Error: core::fmt::Debug + Clone, - >::Error: core::fmt::Debug + Clone, -{ - ReadError(>::Error), - WriteError(>::Error), - BufferFull, - // XXX Other errors? -} - -impl fmt::Display for SerialHandlerError -where - Device: serial::Read + serial::Write, - >::Error: core::fmt::Debug + Clone, - >::Error: core::fmt::Debug + Clone, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - SerialHandlerError::ReadError(_) => write!(f, "SerialHandlerError::ReadError"), - SerialHandlerError::WriteError(_) => write!(f, "SerialHandlerError::WriteError"), - SerialHandlerError::BufferFull => write!(f, "SerialHandlerError::BufferFull"), - } - } -} - -impl Handler for SerialHandler -where - Device: serial::Read + serial::Write + IrqDevice, - >::Error: core::fmt::Debug + Clone, - >::Error: core::fmt::Debug + Clone, -{ - type Error = SerialHandlerError; - - fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { - // TODO Handle errors - if channel == self.serial { - while let Ok(c) = self.device.read() { - if let Err(_) = self.buffer.push_back(c) { - return Err(SerialHandlerError::BufferFull); - } - } - self.device.handle_irq(); - self.serial.irq_ack().unwrap(); - if self.notify { - self.client.notify(); - self.notify = false; - } - } else { - unreachable!() // XXX Is this actually unreachable? - } - Ok(()) - } - - fn protected( - &mut self, - channel: Channel, - msg_info: MessageInfo, - ) -> Result { - // TODO Handle errors - if channel == self.client { - match msg_info.label().try_into().ok() /* XXX Handle errors? */ { - Some(RequestTag::Write) => match msg_info.recv() { - Ok(WriteRequest { val }) => { - // Blocking write - while let Err(nb::Error::WouldBlock) = self.device.write(val) {} - Ok(MessageInfo::send(StatusMessageLabel::Ok, NoMessageValue)) - } - Err(_) => Ok(MessageInfo::send(StatusMessageLabel::Error, NoMessageValue)), - }, - Some(RequestTag::Read) => match self.buffer.pop_front() { - Some(val) => { - Ok(MessageInfo::send(ReadResponseTag::Some, ReadSomeResponse { val })) - } - None => { - self.notify = true; - Ok(MessageInfo::send(ReadResponseTag::None, NoMessageValue)) - } - }, - None => Ok(MessageInfo::send(StatusMessageLabel::Error, NoMessageValue)), - } - } else { - unreachable!() // XXX Is this actually unreachable? - } - } -} - -/// Device-independent embedded_hal::serial interface to a serial-device -/// component. Interact with it using [serial::Read], [serial::Write], -/// and [fmt::Write]. -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct SerialDriver { - pub channel: Channel -} - -impl SerialDriver { - pub fn new(channel: Channel) -> Self { - SerialDriver { channel } - } -} - -#[derive(Clone, Debug)] -pub enum ReadError { - RecvError(MessageInfoRecvError), - InvalidResponse, - EOF, -} - -impl serial::Read for SerialDriver { - type Error = ReadError; - - // XXX Unclear if this blocks or how to prevent it from doing so... - fn read(&mut self) -> nb::Result { - let msg_info = self.channel - .pp_call(MessageInfo::send(RequestTag::Read, NoMessageValue)); - - match msg_info.label().try_into() { - Ok(ReadResponseTag::Some) => match msg_info.recv() { - Ok(ReadSomeResponse { val }) => Ok(val), - Err(e) => Err(nb::Error::Other(ReadError::RecvError(e))), - }, - Ok(ReadResponseTag::None) => Err(nb::Error::Other(ReadError::EOF)), - Err(_) => Err(nb::Error::Other(ReadError::InvalidResponse)), - } - } -} - -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum WriteError { - SendError, - InvalidResponse, -} - -impl serial::Write for SerialDriver { - type Error = WriteError; - - // XXX Unclear if this blocks or how to prevent it from doing so... - fn write(&mut self, val: u8) -> nb::Result<(), Self::Error> { - let msg_info = self.channel - .pp_call(MessageInfo::send(RequestTag::Write, WriteRequest { val })); - - match msg_info.label().try_into() { - Ok(StatusMessageLabel::Ok) => Ok(()), - Ok(StatusMessageLabel::Error) => Err(nb::Error::Other(WriteError::SendError)), - Err(_) => Err(nb::Error::Other(WriteError::InvalidResponse)), - } - } - - fn flush(&mut self) -> nb::Result<(), Self::Error> { - todo!() - } -} - -// XXX There's already an implementation of core::fmt::Write for serial::Write -// in embedded_hal::fmt, but I'm not clear on how to use it. -impl fmt::Write for SerialDriver { - fn write_str(&mut self, s: &str) -> fmt::Result { - s.as_bytes().iter().copied().for_each(|b| { let _ = self.write(b); }); - Ok(()) - } -} - -#[derive(Clone, Copy, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[cfg_attr(target_pointer_width = "32", repr(u32))] -#[cfg_attr(target_pointer_width = "64", repr(u64))] -pub enum RequestTag { - Write, - Read, -} - -#[derive(Clone, Copy, PartialEq, Eq, AsBytes, FromBytes)] -#[repr(C)] -pub struct WriteRequest { - pub val: u8, -} - -#[derive(Clone, Copy, PartialEq, Eq, IntoPrimitive, TryFromPrimitive)] -#[cfg_attr(target_pointer_width = "32", repr(u32))] -#[cfg_attr(target_pointer_width = "64", repr(u64))] -pub enum ReadResponseTag { - None, - Some, -} - -#[derive(Clone, Copy, PartialEq, Eq, AsBytes, FromBytes)] -#[repr(C)] -pub struct ReadSomeResponse { - pub val: u8, -} diff --git a/crates/sel4-hal-adapters/src/smoltcp/phy/device.rs b/crates/sel4-hal-adapters/src/smoltcp/phy/device.rs deleted file mode 100644 index 08456f996..000000000 --- a/crates/sel4-hal-adapters/src/smoltcp/phy/device.rs +++ /dev/null @@ -1,10 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// Copyright 2023, Galois, Inc. -// -// SPDX-License-Identifier: BSD-2-Clause -// - -//! Client-side [`smoltcp::phy::Device`] implementation - -pub use sel4_shared_ring_buffer::*; diff --git a/crates/sel4-immediate-sync-once-cell/src/lib.rs b/crates/sel4-immediate-sync-once-cell/src/lib.rs index 65c1dbcf8..b4e1e6003 100644 --- a/crates/sel4-immediate-sync-once-cell/src/lib.rs +++ b/crates/sel4-immediate-sync-once-cell/src/lib.rs @@ -45,8 +45,9 @@ impl ImmediateSyncOnceCell { if self.init_started.swap(true, Ordering::SeqCst) { Err(value) } else { - let slot = unsafe { &mut *self.inner.get() }; - *slot = Some(value); + unsafe { + *self.inner.get().as_mut().unwrap() = Some(value); + } self.init_completed.store(true, Ordering::SeqCst); Ok(()) } diff --git a/crates/sel4-kernel-loader/Cargo.nix b/crates/sel4-kernel-loader/Cargo.nix index 84efd6bf8..fc6859ad4 100644 --- a/crates/sel4-kernel-loader/Cargo.nix +++ b/crates/sel4-kernel-loader/Cargo.nix @@ -10,10 +10,10 @@ mk { package.name = "sel4-kernel-loader"; package.license = "BSD-2-Clause AND GPL-2.0-only"; dependencies = { - inherit (versions) tock-registers cfg-if log; + inherit (versions) cfg-if log embedded-hal-nb; postcard = postcardWith []; heapless = { version = versions.heapless; features = [ "serde" ]; }; - spin = "0.9.4"; + spin = { version = "0.9.4"; features = [ "lock_api" ]; }; inherit (localCrates) sel4-platform-info sel4-logging @@ -27,6 +27,9 @@ mk { sbi = "0.2.0"; riscv = "0.10.0"; }; + target."cfg(any(target_arch = \"arm\", target_arch = \"aarch64\"))".dependencies = { + inherit (localCrates) sel4-pl011-driver sel4-bcm2835-aux-uart-driver; + }; target."cfg(target_arch = \"aarch64\")".dependencies = { smccc = "0.1.1"; aarch64-cpu = "9.0.0"; diff --git a/crates/sel4-kernel-loader/Cargo.toml b/crates/sel4-kernel-loader/Cargo.toml index ce6e7fbcd..bc4cb2175 100644 --- a/crates/sel4-kernel-loader/Cargo.toml +++ b/crates/sel4-kernel-loader/Cargo.toml @@ -18,6 +18,7 @@ license = "BSD-2-Clause AND GPL-2.0-only" [dependencies] cfg-if = "1.0.0" +embedded-hal-nb = "1.0" heapless = { version = "0.7.16", features = ["serde"] } log = "0.4.17" postcard = { version = "1.0.2", default-features = false } @@ -27,8 +28,7 @@ sel4-kernel-loader-embed-page-tables-runtime = { path = "embed-page-tables/runti sel4-kernel-loader-payload-types = { path = "payload-types", features = ["serde"] } sel4-logging = { path = "../sel4-logging" } sel4-platform-info = { path = "../sel4-platform-info" } -spin = "0.9.4" -tock-registers = "0.8.1" +spin = { version = "0.9.4", features = ["lock_api"] } [build-dependencies] cc = "1.0.76" @@ -45,6 +45,10 @@ sel4-platform-info = { path = "../sel4-platform-info" } sel4-rustfmt-helper = { path = "../sel4-rustfmt-helper" } serde = "1.0.147" +[target."cfg(any(target_arch = \"arm\", target_arch = \"aarch64\"))".dependencies] +sel4-bcm2835-aux-uart-driver = { path = "../drivers/bcm2835-aux-uart" } +sel4-pl011-driver = { path = "../drivers/pl011" } + [target."cfg(any(target_arch = \"riscv32\", target_arch = \"riscv64\"))".dependencies] riscv = "0.10.0" sbi = "0.2.0" diff --git a/crates/sel4-kernel-loader/src/arch/arm/arch/aarch64/mod.rs b/crates/sel4-kernel-loader/src/arch/arm/arch/aarch64/mod.rs index e12824166..95d23302c 100644 --- a/crates/sel4-kernel-loader/src/arch/arm/arch/aarch64/mod.rs +++ b/crates/sel4-kernel-loader/src/arch/arm/arch/aarch64/mod.rs @@ -7,8 +7,7 @@ use core::arch::asm; use core::mem; -use aarch64_cpu::registers::CurrentEL; -use tock_registers::interfaces::Readable; +use aarch64_cpu::registers::{CurrentEL, Readable}; use sel4_kernel_loader_payload_types::PayloadInfo; diff --git a/crates/sel4-kernel-loader/src/drivers/mod.rs b/crates/sel4-kernel-loader/src/drivers/mod.rs deleted file mode 100644 index 5219678b8..000000000 --- a/crates/sel4-kernel-loader/src/drivers/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -pub(crate) mod bcm2835_aux_uart; -pub(crate) mod pl011; diff --git a/crates/sel4-kernel-loader/src/drivers/pl011.rs b/crates/sel4-kernel-loader/src/drivers/pl011.rs deleted file mode 100644 index 4e067ef17..000000000 --- a/crates/sel4-kernel-loader/src/drivers/pl011.rs +++ /dev/null @@ -1,69 +0,0 @@ -// -// Copyright 2023, Colias Group, LLC -// -// SPDX-License-Identifier: BSD-2-Clause -// - -#![allow(dead_code)] - -use core::ops::Deref; - -use tock_registers::{ - interfaces::{Readable, Writeable}, - register_structs, - registers::ReadWrite, -}; - -const PL011_UARTFR_TXFF: u32 = 1 << 5; -const PL011_UARTFR_RXFE: u32 = 1 << 4; - -register_structs! { - #[allow(non_snake_case)] - pub(crate)Pl011RegisterBlock { - (0x000 => DR: ReadWrite), - (0x001 => _reserved0), - (0x018 => FR: ReadWrite), - (0x01c => _reserved1), - (0x038 => IMSC: ReadWrite), - (0x03c => _reserved2), - (0x044 => ICR: ReadWrite), - (0x048 => @END), - } -} - -pub(crate) struct Pl011Device { - base_addr: usize, -} - -impl Pl011Device { - pub(crate) const unsafe fn new(base_addr: usize) -> Self { - Self { base_addr } - } - - fn ptr(&self) -> *const Pl011RegisterBlock { - self.base_addr as *const _ - } - - pub(crate) fn init(&self) { - self.IMSC.set(0x50); - } -} - -impl Deref for Pl011Device { - type Target = Pl011RegisterBlock; - - fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } - } -} - -impl Pl011Device { - pub(crate) fn put_char(&self, c: u8) { - loop { - if self.FR.get() & PL011_UARTFR_TXFF == 0 { - break; - } - } - self.DR.set(c) - } -} diff --git a/crates/sel4-kernel-loader/src/logging.rs b/crates/sel4-kernel-loader/src/logging.rs index 73e5b7cda..fce783ba6 100644 --- a/crates/sel4-kernel-loader/src/logging.rs +++ b/crates/sel4-kernel-loader/src/logging.rs @@ -4,16 +4,15 @@ // SPDX-License-Identifier: BSD-2-Clause // -use log::{Log, Metadata, Record}; use spin::Mutex; -use sel4_logging::{LevelFilter, Logger, LoggerBuilder}; +use sel4_logging::{LevelFilter, Logger, LoggerBuilder, SynchronizedLogger}; use crate::fmt::debug_print; const LOG_LEVEL: LevelFilter = LevelFilter::Debug; -static LOGGER: SynchronizedLogger = SynchronizedLogger::new( +static LOGGER: SynchronizedLogger, Logger> = SynchronizedLogger::new( LoggerBuilder::const_default() .level_filter(LOG_LEVEL) .write(|s| debug_print!("{}", s)) @@ -29,28 +28,6 @@ static LOGGER: SynchronizedLogger = SynchronizedLogger::new( ); pub(crate) fn set_logger() { - log::set_max_level(LOGGER.0.lock().level_filter); + log::set_max_level(LOGGER.inner().lock().level_filter); log::set_logger(&LOGGER).unwrap(); } - -struct SynchronizedLogger(Mutex); - -impl SynchronizedLogger { - const fn new(inner: T) -> Self { - Self(Mutex::new(inner)) - } -} - -impl Log for SynchronizedLogger { - fn enabled(&self, metadata: &Metadata) -> bool { - self.0.lock().enabled(metadata) - } - - fn log(&self, record: &Record) { - self.0.lock().log(record) - } - - fn flush(&self) { - self.0.lock().flush() - } -} diff --git a/crates/sel4-kernel-loader/src/main.rs b/crates/sel4-kernel-loader/src/main.rs index 86ae720d9..87e384b58 100644 --- a/crates/sel4-kernel-loader/src/main.rs +++ b/crates/sel4-kernel-loader/src/main.rs @@ -17,7 +17,6 @@ use sel4_platform_info::PLATFORM_INFO; mod arch; mod barrier; -mod drivers; mod fmt; mod logging; mod plat; diff --git a/crates/sel4-kernel-loader/src/plat/bcm2711/mod.rs b/crates/sel4-kernel-loader/src/plat/bcm2711/mod.rs index 69013f848..023970126 100644 --- a/crates/sel4-kernel-loader/src/plat/bcm2711/mod.rs +++ b/crates/sel4-kernel-loader/src/plat/bcm2711/mod.rs @@ -4,25 +4,28 @@ // SPDX-License-Identifier: BSD-2-Clause // -use spin::Mutex; +use embedded_hal_nb::nb; +use embedded_hal_nb::serial::Write; +use spin::lock_api::Mutex; +use sel4_bcm2835_aux_uart_driver::Driver as Bcm2835AuxUartDriver; use sel4_config::{sel4_cfg, sel4_cfg_bool}; -use crate::{arch::reset_cntvoff, drivers::bcm2835_aux_uart::Bcm2835AuxUartDevice, plat::Plat}; +use crate::{arch::reset_cntvoff, plat::Plat}; const SERIAL_DEVICE_BASE_ADDR: usize = 0xfe21_5000; -static SERIAL_DEVICE: Mutex = Mutex::new(get_serial_device()); +static SERIAL_DRIVER: Mutex = Mutex::new(get_serial_driver()); -const fn get_serial_device() -> Bcm2835AuxUartDevice { - unsafe { Bcm2835AuxUartDevice::new(SERIAL_DEVICE_BASE_ADDR) } +const fn get_serial_driver() -> Bcm2835AuxUartDriver { + unsafe { Bcm2835AuxUartDriver::new_uninit(SERIAL_DEVICE_BASE_ADDR as *mut _) } } pub(crate) enum PlatImpl {} impl Plat for PlatImpl { fn init() { - SERIAL_DEVICE.lock().init(); + SERIAL_DRIVER.lock().init(); } fn init_per_core() { @@ -34,11 +37,11 @@ impl Plat for PlatImpl { } fn put_char(c: u8) { - SERIAL_DEVICE.lock().put_char(c); + nb::block!(SERIAL_DRIVER.lock().write(c)).unwrap_or_else(|err| match err {}); } fn put_char_without_synchronization(c: u8) { - get_serial_device().put_char(c); + nb::block!(get_serial_driver().write(c)).unwrap_or_else(|err| match err {}); } #[sel4_cfg(ARCH_AARCH64)] diff --git a/crates/sel4-kernel-loader/src/plat/qemu_arm_virt/mod.rs b/crates/sel4-kernel-loader/src/plat/qemu_arm_virt/mod.rs index d9fecb2ac..a721036a9 100644 --- a/crates/sel4-kernel-loader/src/plat/qemu_arm_virt/mod.rs +++ b/crates/sel4-kernel-loader/src/plat/qemu_arm_virt/mod.rs @@ -4,29 +4,31 @@ // SPDX-License-Identifier: BSD-2-Clause // -use spin::Mutex; +use embedded_hal_nb::nb; +use embedded_hal_nb::serial::Write; +use spin::lock_api::Mutex; use sel4_config::sel4_cfg_bool; +use sel4_pl011_driver::Driver as Pl011Driver; use crate::{ arch::{drivers::psci, reset_cntvoff}, - drivers::pl011::Pl011Device, plat::Plat, }; const SERIAL_DEVICE_BASE_ADDR: usize = 0x0900_0000; -static SERIAL_DEVICE: Mutex = Mutex::new(get_serial_device()); +static SERIAL_DRIVER: Mutex = Mutex::new(get_serial_driver()); -const fn get_serial_device() -> Pl011Device { - unsafe { Pl011Device::new(SERIAL_DEVICE_BASE_ADDR) } +const fn get_serial_driver() -> Pl011Driver { + unsafe { Pl011Driver::new_uninit(SERIAL_DEVICE_BASE_ADDR as *mut _) } } pub(crate) enum PlatImpl {} impl Plat for PlatImpl { fn init() { - SERIAL_DEVICE.lock().init(); + SERIAL_DRIVER.lock().init(); } fn init_per_core() { @@ -38,11 +40,11 @@ impl Plat for PlatImpl { } fn put_char(c: u8) { - SERIAL_DEVICE.lock().put_char(c); + nb::block!(SERIAL_DRIVER.lock().write(c)).unwrap_or_else(|err| match err {}); } fn put_char_without_synchronization(c: u8) { - get_serial_device().put_char(c); + nb::block!(get_serial_driver().write(c)).unwrap_or_else(|err| match err {}); } fn start_secondary_core(core_id: usize, sp: usize) { diff --git a/crates/sel4-logging/Cargo.nix b/crates/sel4-logging/Cargo.nix index f6f6ad0ed..93fb4ded2 100644 --- a/crates/sel4-logging/Cargo.nix +++ b/crates/sel4-logging/Cargo.nix @@ -9,6 +9,6 @@ mk { package.name = "sel4-logging"; dependencies = { - inherit (versions) log; + inherit (versions) log lock_api; }; } diff --git a/crates/sel4-logging/Cargo.toml b/crates/sel4-logging/Cargo.toml index aaf8e7c00..9dc529506 100644 --- a/crates/sel4-logging/Cargo.toml +++ b/crates/sel4-logging/Cargo.toml @@ -17,4 +17,5 @@ edition = "2021" license = "BSD-2-Clause" [dependencies] +lock_api = "0.4.12" log = "0.4.17" diff --git a/crates/sel4-logging/src/lib.rs b/crates/sel4-logging/src/lib.rs index cc8179ae2..52ab09e68 100644 --- a/crates/sel4-logging/src/lib.rs +++ b/crates/sel4-logging/src/lib.rs @@ -12,6 +12,10 @@ use log::{Log, Metadata, Record, SetLoggerError}; pub use log::{self, LevelFilter}; +mod synchronized; + +pub use synchronized::SynchronizedLogger; + pub struct Logger { pub level_filter: LevelFilter, pub filter: fn(&Metadata) -> bool, diff --git a/crates/sel4-logging/src/synchronized.rs b/crates/sel4-logging/src/synchronized.rs new file mode 100644 index 000000000..89354b573 --- /dev/null +++ b/crates/sel4-logging/src/synchronized.rs @@ -0,0 +1,48 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use lock_api::{Mutex, RawMutex}; +use log::{Log, Metadata, Record}; + +pub struct SynchronizedLogger(Mutex); + +impl SynchronizedLogger { + pub const fn new(inner: T) -> Self { + Self(Mutex::new(inner)) + } +} + +impl SynchronizedLogger { + pub const fn from_raw(raw_mutex: R, inner: T) -> Self { + Self(Mutex::from_raw(raw_mutex, inner)) + } + + pub fn into_inner(self) -> Mutex { + self.0 + } + + pub fn inner(&self) -> &Mutex { + &self.0 + } + + pub fn inner_mut(&mut self) -> &mut Mutex { + &mut self.0 + } +} + +impl Log for SynchronizedLogger { + fn enabled(&self, metadata: &Metadata) -> bool { + self.inner().lock().enabled(metadata) + } + + fn log(&self, record: &Record) { + self.inner().lock().log(record) + } + + fn flush(&self) { + self.inner().lock().flush() + } +} diff --git a/crates/sel4-microkit/driver-adapters/Cargo.nix b/crates/sel4-microkit/driver-adapters/Cargo.nix new file mode 100644 index 000000000..ee3b03ba0 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/Cargo.nix @@ -0,0 +1,34 @@ +# +# Copyright 2023, Colias Group, LLC +# Copyright 2023, Galois, Inc. +# +# SPDX-License-Identifier: BSD-2-Clause +# + +{ mk, versions, localCrates, serdeWith, smoltcpWith, authors }: + +mk { + package.name = "sel4-microkit-driver-adapters"; + package.authors = with authors; [ + nspin + "Ben Hamlin " + ]; + dependencies = { + inherit (versions) log embedded-hal-nb heapless rtcc; + serde = serdeWith []; + smoltcp = smoltcpWith []; + chrono = { version = versions.chrono; default-features = false; features = [ "serde" ]; }; + } // (with localCrates; { + inherit + sel4-driver-interfaces + sel4-microkit-message + sel4-shared-ring-buffer + sel4-bounce-buffer-allocator + ; + sel4-externally-shared = sel4-externally-shared // { features = [ "unstable" ]; }; + sel4-microkit = sel4-microkit // { default-features = false; }; + }); + features = { + # TODO + }; +} diff --git a/crates/sel4-hal-adapters/Cargo.toml b/crates/sel4-microkit/driver-adapters/Cargo.toml similarity index 53% rename from crates/sel4-hal-adapters/Cargo.toml rename to crates/sel4-microkit/driver-adapters/Cargo.toml index 2f5357367..76e268c8a 100644 --- a/crates/sel4-hal-adapters/Cargo.toml +++ b/crates/sel4-microkit/driver-adapters/Cargo.toml @@ -10,36 +10,27 @@ # [package] -name = "sel4-hal-adapters" +name = "sel4-microkit-driver-adapters" version = "0.1.0" authors = ["Nick Spinale ", "Ben Hamlin "] edition = "2021" license = "BSD-2-Clause" -[features] -default = ["smoltcp-hal"] -smoltcp-hal = [ - "smoltcp", - "sel4-shared-ring-buffer", - "sel4-externally-shared", - "sel4-bounce-buffer-allocator", -] - [dependencies] +chrono = { version = "0.4.35", default-features = false, features = ["serde"] } +embedded-hal-nb = "1.0" +heapless = "0.7.16" log = "0.4.17" -sel4-bounce-buffer-allocator = { path = "../sel4-bounce-buffer-allocator", optional = true } -sel4-microkit = { path = "../sel4-microkit", default-features = false } -sel4-microkit-message = { path = "../sel4-microkit/message" } -sel4-shared-ring-buffer = { path = "../sel4-shared-ring-buffer", optional = true } +rtcc = "0.3.2" +sel4-bounce-buffer-allocator = { path = "../../sel4-bounce-buffer-allocator" } +sel4-driver-interfaces = { path = "../../sel4-driver-interfaces" } +sel4-externally-shared = { path = "../../sel4-externally-shared", features = ["unstable"] } +sel4-microkit = { path = "..", default-features = false } +sel4-microkit-message = { path = "../message" } +sel4-shared-ring-buffer = { path = "../../sel4-shared-ring-buffer" } serde = { version = "1.0.147", default-features = false } -[dependencies.sel4-externally-shared] -path = "../sel4-externally-shared" -features = ["unstable"] -optional = true - [dependencies.smoltcp] version = "0.10.0" default-features = false features = ["proto-ipv4", "proto-dhcpv4", "proto-dns", "socket-dhcpv4", "socket-dns", "socket-tcp"] -optional = true diff --git a/crates/sel4-microkit/driver-adapters/src/block/client.rs b/crates/sel4-microkit/driver-adapters/src/block/client.rs new file mode 100644 index 000000000..73b7b6bee --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/block/client.rs @@ -0,0 +1,54 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use sel4_driver_interfaces::block::GetBlockDeviceLayout; +use sel4_microkit::{Channel, MessageInfo}; +use sel4_microkit_message::MessageInfoExt as _; + +use super::message_types::*; + +pub struct Client { + channel: Channel, +} + +impl Client { + pub fn new(channel: Channel) -> Self { + Self { channel } + } + + fn request(&self, req: Request) -> Result { + self.channel + .pp_call(MessageInfo::send_using_postcard(req).unwrap()) + .recv_using_postcard::() + .map_err(|_| Error::InvalidResponse)? + .map_err(Error::ErrorResponse) + } +} + +impl GetBlockDeviceLayout for Client { + type Error = Error; + + fn get_block_size(&mut self) -> Result { + match self.request(Request::GetBlockSize)? { + SuccessResponse::GetBlockSize(size) => Ok(size), + _ => Err(Error::UnexpectedResponse), + } + } + + fn get_num_blocks(&mut self) -> Result { + match self.request(Request::GetNumBlocks)? { + SuccessResponse::GetNumBlocks(n) => Ok(n), + _ => Err(Error::UnexpectedResponse), + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Error { + ErrorResponse(ErrorResponse), + InvalidResponse, + UnexpectedResponse, +} diff --git a/crates/sel4-microkit/driver-adapters/src/block/driver.rs b/crates/sel4-microkit/driver-adapters/src/block/driver.rs new file mode 100644 index 000000000..9a0682310 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/block/driver.rs @@ -0,0 +1,33 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use sel4_driver_interfaces::block::GetBlockDeviceLayout; +use sel4_microkit::MessageInfo; +use sel4_microkit_message::MessageInfoExt as _; + +use super::message_types::*; + +pub fn handle_client_request( + dev: &mut T, + msg_info: MessageInfo, +) -> MessageInfo { + match msg_info.recv_using_postcard::() { + Ok(req) => { + let resp: Response = match req { + Request::GetNumBlocks => dev + .get_num_blocks() + .map(SuccessResponse::GetNumBlocks) + .map_err(|_| ErrorResponse::Unspecified), + Request::GetBlockSize => dev + .get_block_size() + .map(SuccessResponse::GetBlockSize) + .map_err(|_| ErrorResponse::Unspecified), + }; + MessageInfo::send_using_postcard(resp).unwrap() + } + Err(_) => MessageInfo::send_unspecified_error(), + } +} diff --git a/crates/sel4-microkit/driver-adapters/src/block/message_types.rs b/crates/sel4-microkit/driver-adapters/src/block/message_types.rs new file mode 100644 index 000000000..a2530d618 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/block/message_types.rs @@ -0,0 +1,26 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum Request { + GetBlockSize, + GetNumBlocks, +} + +pub(crate) type Response = Result; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum SuccessResponse { + GetBlockSize(usize), + GetNumBlocks(u64), +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum ErrorResponse { + Unspecified, +} diff --git a/crates/sel4-microkit/driver-adapters/src/block/mod.rs b/crates/sel4-microkit/driver-adapters/src/block/mod.rs new file mode 100644 index 000000000..5d29bcbd8 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/block/mod.rs @@ -0,0 +1,12 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +mod message_types; + +pub mod client; +pub mod driver; + +pub use message_types::ErrorResponse; diff --git a/crates/sel4-hal-adapters/src/lib.rs b/crates/sel4-microkit/driver-adapters/src/lib.rs similarity index 64% rename from crates/sel4-hal-adapters/src/lib.rs rename to crates/sel4-microkit/driver-adapters/src/lib.rs index cfddfafdd..85c2e252f 100644 --- a/crates/sel4-hal-adapters/src/lib.rs +++ b/crates/sel4-microkit/driver-adapters/src/lib.rs @@ -7,5 +7,8 @@ #![no_std] -#[cfg(feature = "smoltcp-hal")] -pub mod smoltcp; +pub mod block; +pub mod net; +pub mod rtc; +pub mod serial; +pub mod timer; diff --git a/crates/sel4-microkit/driver-adapters/src/net/client.rs b/crates/sel4-microkit/driver-adapters/src/net/client.rs new file mode 100644 index 000000000..7663c10cc --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/net/client.rs @@ -0,0 +1,48 @@ +// +// Copyright 2024, Colias Group, LLC +// Copyright 2023, Galois, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use sel4_driver_interfaces::net::{GetNetDeviceMeta, MacAddress}; +use sel4_microkit::{Channel, MessageInfo}; +use sel4_microkit_message::MessageInfoExt as _; + +use super::message_types::*; + +pub struct Client { + channel: Channel, +} + +impl Client { + pub fn new(channel: Channel) -> Self { + Self { channel } + } + + fn request(&self, req: Request) -> Result { + self.channel + .pp_call(MessageInfo::send_using_postcard(req).unwrap()) + .recv_using_postcard::() + .map_err(|_| Error::InvalidResponse)? + .map_err(Error::ErrorResponse) + } +} + +impl GetNetDeviceMeta for Client { + type Error = Error; + + fn get_mac_address(&mut self) -> Result { + match self.request(Request::GetMacAddress)? { + SuccessResponse::GetMacAddress(mac_address) => Ok(mac_address), + // _ => Err(Error::UnexpectedResponse), + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Error { + ErrorResponse(ErrorResponse), + InvalidResponse, + UnexpectedResponse, +} diff --git a/crates/sel4-hal-adapters/src/smoltcp/phy/handler.rs b/crates/sel4-microkit/driver-adapters/src/net/driver.rs similarity index 63% rename from crates/sel4-hal-adapters/src/smoltcp/phy/handler.rs rename to crates/sel4-microkit/driver-adapters/src/net/driver.rs index a71995866..f3986b7f5 100644 --- a/crates/sel4-hal-adapters/src/smoltcp/phy/handler.rs +++ b/crates/sel4-microkit/driver-adapters/src/net/driver.rs @@ -12,60 +12,36 @@ use smoltcp::{ time::Instant, }; -use serde::{Deserialize, Serialize}; - +use sel4_driver_interfaces::net::GetNetDeviceMeta; +use sel4_driver_interfaces::HandleInterrupt; use sel4_externally_shared::ExternallySharedRef; use sel4_microkit::{Channel, Handler, Infallible, MessageInfo}; use sel4_microkit_message::MessageInfoExt as _; use sel4_shared_ring_buffer::{roles::Use, RingBuffers}; -pub trait IrqAck { - fn irq_ack(&mut self); -} - -pub trait HasMac { - fn mac_address(&self) -> [u8; 6]; -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct MacAddress(pub [u8; 6]); - -#[derive(Debug, Serialize, Deserialize)] -pub enum Request { - GetMacAddress, -} +use super::message_types::*; -#[derive(Debug, Serialize, Deserialize)] -pub struct GetMacAddressResponse { - pub mac_address: MacAddress, -} - -pub struct PhyDeviceHandler { +pub struct HandlerImpl { dev: Device, client_region: ExternallySharedRef<'static, [u8]>, - client_region_paddr: usize, - rx_ring_buffers: RingBuffers<'static, Use, fn() -> Result<(), Infallible>>, - tx_ring_buffers: RingBuffers<'static, Use, fn() -> Result<(), Infallible>>, + rx_ring_buffers: RingBuffers<'static, Use, fn()>, + tx_ring_buffers: RingBuffers<'static, Use, fn()>, device_channel: Channel, client_channel: Channel, } -impl PhyDeviceHandler { +impl HandlerImpl { pub fn new( dev: Device, client_region: ExternallySharedRef<'static, [u8]>, - client_region_paddr: usize, - rx_ring_buffers: RingBuffers<'static, Use, fn() -> Result<(), Infallible>>, - tx_ring_buffers: RingBuffers<'static, Use, fn() -> Result<(), Infallible>>, + rx_ring_buffers: RingBuffers<'static, Use, fn()>, + tx_ring_buffers: RingBuffers<'static, Use, fn()>, device_channel: Channel, client_channel: Channel, ) -> Self { - // XXX We could maybe initialize DMA here, so we don't need to do - // it in main. Also maybe initialize the ring buffers. Self { dev, client_region, - client_region_paddr, rx_ring_buffers, tx_ring_buffers, device_channel, @@ -74,7 +50,7 @@ impl PhyDeviceHandler { } } -impl Handler for PhyDeviceHandler { +impl Handler for HandlerImpl { type Error = Infallible; fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { @@ -93,7 +69,7 @@ impl Handler for PhyDeviceHandler rx_tok.consume(|rx_buf| { assert!(desc_len >= rx_buf.len()); let buf_range = { - let start = desc.encoded_addr() - self.client_region_paddr; + let start = desc.encoded_addr(); start..start + rx_buf.len() }; self.client_region @@ -111,7 +87,7 @@ impl Handler for PhyDeviceHandler } if notify_rx { - self.rx_ring_buffers.notify().unwrap(); + self.rx_ring_buffers.notify(); } let mut notify_tx = false; @@ -127,7 +103,7 @@ impl Handler for PhyDeviceHandler tx_tok.consume(tx_len, |tx_buf| { let buf_range = { - let start = desc.encoded_addr() - self.client_region_paddr; + let start = desc.encoded_addr(); start..start + tx_len }; self.client_region @@ -145,10 +121,10 @@ impl Handler for PhyDeviceHandler } if notify_tx { - self.tx_ring_buffers.notify().unwrap(); + self.tx_ring_buffers.notify(); } - self.dev.irq_ack(); + self.dev.handle_interrupt(); self.device_channel.irq_ack().unwrap(); } else { unreachable!() @@ -162,21 +138,28 @@ impl Handler for PhyDeviceHandler channel: Channel, msg_info: MessageInfo, ) -> Result { - Ok(if channel == self.client_channel { - match msg_info.recv_using_postcard::() { - Ok(req) => match req { - Request::GetMacAddress => { - let mac_address = self.dev.mac_address(); - MessageInfo::send_using_postcard(GetMacAddressResponse { - mac_address: MacAddress(mac_address), - }) - .unwrap() - } - }, - Err(_) => MessageInfo::send_unspecified_error(), - } + if channel == self.client_channel { + Ok(handle_client_request(&mut self.dev, msg_info)) } else { unreachable!() - }) + } + } +} + +pub fn handle_client_request( + dev: &mut T, + msg_info: MessageInfo, +) -> MessageInfo { + match msg_info.recv_using_postcard::() { + Ok(req) => { + let resp: Response = match req { + Request::GetMacAddress => dev + .get_mac_address() + .map(SuccessResponse::GetMacAddress) + .map_err(|_| ErrorResponse::Unspecified), + }; + MessageInfo::send_using_postcard(resp).unwrap() + } + Err(_) => MessageInfo::send_unspecified_error(), } } diff --git a/crates/sel4-microkit/driver-adapters/src/net/message_types.rs b/crates/sel4-microkit/driver-adapters/src/net/message_types.rs new file mode 100644 index 000000000..14a7f2833 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/net/message_types.rs @@ -0,0 +1,27 @@ +// +// Copyright 2023, Colias Group, LLC +// Copyright 2023, Galois, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use serde::{Deserialize, Serialize}; + +use sel4_driver_interfaces::net::MacAddress; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum Request { + GetMacAddress, +} + +pub(crate) type Response = Result; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum SuccessResponse { + GetMacAddress(MacAddress), +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum ErrorResponse { + Unspecified, +} diff --git a/crates/sel4-hal-adapters/src/smoltcp/phy/mod.rs b/crates/sel4-microkit/driver-adapters/src/net/mod.rs similarity index 57% rename from crates/sel4-hal-adapters/src/smoltcp/phy/mod.rs rename to crates/sel4-microkit/driver-adapters/src/net/mod.rs index ca7e318a0..a87bbfb09 100644 --- a/crates/sel4-hal-adapters/src/smoltcp/phy/mod.rs +++ b/crates/sel4-microkit/driver-adapters/src/net/mod.rs @@ -5,8 +5,9 @@ // SPDX-License-Identifier: BSD-2-Clause // -mod handler; -pub use handler::*; +mod message_types; -mod device; -pub use device::*; +pub mod client; +pub mod driver; + +pub use message_types::ErrorResponse; diff --git a/crates/sel4-microkit/driver-adapters/src/rtc/client.rs b/crates/sel4-microkit/driver-adapters/src/rtc/client.rs new file mode 100644 index 000000000..a830cbd7a --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/rtc/client.rs @@ -0,0 +1,59 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use rtcc::{DateTimeAccess, NaiveDateTime}; + +use sel4_microkit::{Channel, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +/// Device-independent embedded_hal_nb::serial interface to a serial-device +/// component. Interact with it using [serial::Read], [serial::Write], +/// and [fmt::Write]. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Client { + channel: Channel, +} + +impl Client { + pub fn new(channel: Channel) -> Self { + Client { channel } + } + + fn request(&self, req: Request) -> Result { + self.channel + .pp_call(MessageInfo::send_using_postcard(req).unwrap()) + .recv_using_postcard::() + .map_err(|_| Error::InvalidResponse)? + .map_err(Error::ErrorResponse) + } +} + +impl DateTimeAccess for Client { + type Error = Error; + + fn datetime(&mut self) -> Result { + match self.request(Request::DateTime)? { + SuccessResponse::DateTime(v) => Ok(v), + _ => Err(Error::UnexpectedResponse), + } + } + + fn set_datetime(&mut self, v: &NaiveDateTime) -> Result<(), Self::Error> { + match self.request(Request::SetDateTime(*v))? { + SuccessResponse::SetDateTime => Ok(()), + _ => Err(Error::UnexpectedResponse), + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Error { + ErrorResponse(ErrorResponse), + InvalidResponse, + UnexpectedResponse, +} diff --git a/crates/sel4-microkit/driver-adapters/src/rtc/driver.rs b/crates/sel4-microkit/driver-adapters/src/rtc/driver.rs new file mode 100644 index 000000000..ad9f774b8 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/rtc/driver.rs @@ -0,0 +1,63 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::convert::Infallible; + +use rtcc::DateTimeAccess; + +use sel4_microkit::{Channel, Handler, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +/// Handle messages using an implementor of [serial::Read] and [serial::Write]. +#[derive(Clone, Debug)] +pub struct HandlerImpl { + driver: Driver, + client: Channel, +} + +impl HandlerImpl { + pub fn new(driver: Driver, client: Channel) -> Self { + Self { driver, client } + } +} + +impl Handler for HandlerImpl +where + Driver: DateTimeAccess, +{ + type Error = Infallible; + + fn protected( + &mut self, + channel: Channel, + msg_info: MessageInfo, + ) -> Result { + if channel == self.client { + Ok(match msg_info.recv_using_postcard::() { + Ok(req) => { + let resp = match req { + Request::DateTime => self + .driver + .datetime() + .map(SuccessResponse::DateTime) + .map_err(|_| ErrorResponse::DateTimeError), + Request::SetDateTime(v) => self + .driver + .set_datetime(&v) + .map(|_| SuccessResponse::SetDateTime) + .map_err(|_| ErrorResponse::SetDateTimeError), + }; + MessageInfo::send_using_postcard(resp).unwrap() + } + Err(_) => MessageInfo::send_unspecified_error(), + }) + } else { + panic!("unexpected channel: {channel:?}"); + } + } +} diff --git a/crates/sel4-microkit/driver-adapters/src/rtc/message_types.rs b/crates/sel4-microkit/driver-adapters/src/rtc/message_types.rs new file mode 100644 index 000000000..54ff539fa --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/rtc/message_types.rs @@ -0,0 +1,28 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use rtcc::NaiveDateTime; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum Request { + DateTime, + SetDateTime(NaiveDateTime), +} + +pub(crate) type Response = Result; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum SuccessResponse { + DateTime(NaiveDateTime), + SetDateTime, +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum ErrorResponse { + DateTimeError, + SetDateTimeError, +} diff --git a/crates/sel4-microkit/driver-adapters/src/rtc/mod.rs b/crates/sel4-microkit/driver-adapters/src/rtc/mod.rs new file mode 100644 index 000000000..5d29bcbd8 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/rtc/mod.rs @@ -0,0 +1,12 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +mod message_types; + +pub mod client; +pub mod driver; + +pub use message_types::ErrorResponse; diff --git a/crates/sel4-microkit/driver-adapters/src/serial/client.rs b/crates/sel4-microkit/driver-adapters/src/serial/client.rs new file mode 100644 index 000000000..e1df31641 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/serial/client.rs @@ -0,0 +1,78 @@ +// +// Copyright 2023, Colias Group, LLC +// Copyright 2023, Galois, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use embedded_hal_nb::nb; +use embedded_hal_nb::serial; + +use sel4_microkit::{Channel, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +/// Device-independent embedded_hal_nb::serial interface to a serial-device +/// component. Interact with it using [serial::Read], [serial::Write], +/// and [fmt::Write]. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Client { + channel: Channel, +} + +impl Client { + pub fn new(channel: Channel) -> Self { + Client { channel } + } + + fn request(&self, req: Request) -> Result { + self.channel + .pp_call(MessageInfo::send_using_postcard(req).unwrap()) + .recv_using_postcard::() + .map_err(|_| Error::InvalidResponse)? + .map_err(Error::ErrorResponse) + } +} + +impl serial::ErrorType for Client { + type Error = Error; +} + +impl serial::Read for Client { + fn read(&mut self) -> nb::Result { + match self.request(Request::Read)? { + SuccessResponse::Read(v) => v.into(), + _ => Err(Error::UnexpectedResponse.into()), + } + } +} + +impl serial::Write for Client { + fn write(&mut self, v: u8) -> nb::Result<(), Self::Error> { + match self.request(Request::Write(v))? { + SuccessResponse::Write(v) => v.into(), + _ => Err(Error::UnexpectedResponse.into()), + } + } + + fn flush(&mut self) -> nb::Result<(), Self::Error> { + match self.request(Request::Flush)? { + SuccessResponse::Flush(v) => v.into(), + _ => Err(Error::UnexpectedResponse.into()), + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Error { + ErrorResponse(ErrorResponse), + InvalidResponse, + UnexpectedResponse, +} + +impl serial::Error for Error { + fn kind(&self) -> serial::ErrorKind { + serial::ErrorKind::Other + } +} diff --git a/crates/sel4-microkit/driver-adapters/src/serial/driver.rs b/crates/sel4-microkit/driver-adapters/src/serial/driver.rs new file mode 100644 index 000000000..c11650624 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/serial/driver.rs @@ -0,0 +1,115 @@ +// +// Copyright 2023, Colias Group, LLC +// Copyright 2023, Galois, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::convert::Infallible; + +use embedded_hal_nb::nb; +use embedded_hal_nb::serial; +use heapless::Deque; + +use sel4_driver_interfaces::HandleInterrupt; +use sel4_microkit::{Channel, Handler, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +/// Handle messages using an implementor of [serial::Read] and [serial::Write]. +#[derive(Clone, Debug)] +pub struct HandlerImpl { + /// Driver implementing [serial::Read] and [serial::Write]. + driver: Driver, + /// Channel for this component. + serial: Channel, + /// Channel for client component. + client: Channel, + /// Read buffer. + buffer: Deque, + /// Whether to notify client. + notify: bool, +} + +impl HandlerImpl +where + Driver: serial::Read + serial::Write + HandleInterrupt, +{ + pub fn new(driver: Driver, serial: Channel, client: Channel) -> Self { + Self { + driver, + serial, + client, + buffer: Deque::new(), + notify: true, + } + } +} + +impl Handler for HandlerImpl +where + Driver: serial::Read + serial::Write + HandleInterrupt, +{ + type Error = Infallible; + + fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { + if channel == self.serial { + while !self.buffer.is_full() { + match self.driver.read() { + Ok(v) => { + self.buffer.push_back(v).unwrap(); + } + Err(err) => { + if let nb::Error::Other(err) = err { + // TODO somehow inform the client + log::debug!("read error: {err:?}") + } + break; + } + } + } + self.driver.handle_interrupt(); + self.serial.irq_ack().unwrap(); + if self.notify { + self.client.notify(); + self.notify = false; + } + } else { + panic!("unexpected channel: {channel:?}"); + } + Ok(()) + } + + fn protected( + &mut self, + channel: Channel, + msg_info: MessageInfo, + ) -> Result { + if channel == self.client { + Ok(match msg_info.recv_using_postcard::() { + Ok(req) => { + let resp = match req { + Request::Read => { + let v = self.buffer.pop_front(); + if v.is_some() { + self.notify = true; + } + Ok(SuccessResponse::Read(v.into())) + } + Request::Write(c) => NonBlocking::from_nb_result(self.driver.write(c)) + .map(SuccessResponse::Write) + .map_err(|_| ErrorResponse::WriteError), + Request::Flush => NonBlocking::from_nb_result(self.driver.flush()) + .map(SuccessResponse::Flush) + .map_err(|_| ErrorResponse::FlushError), + }; + MessageInfo::send_using_postcard(resp).unwrap() + } + Err(_) => MessageInfo::send_unspecified_error(), + }) + } else { + panic!("unexpected channel: {channel:?}"); + } + } +} diff --git a/crates/sel4-microkit/driver-adapters/src/serial/message_types.rs b/crates/sel4-microkit/driver-adapters/src/serial/message_types.rs new file mode 100644 index 000000000..cd93f094d --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/serial/message_types.rs @@ -0,0 +1,65 @@ +// +// Copyright 2023, Colias Group, LLC +// Copyright 2023, Galois, Inc. +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use embedded_hal_nb::nb; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum NonBlocking { + Ready(T), + WouldBlock, +} + +impl NonBlocking { + pub(crate) fn from_nb_result(r: nb::Result) -> Result { + match r { + Ok(v) => Ok(Self::Ready(v)), + Err(nb::Error::WouldBlock) => Ok(Self::WouldBlock), + Err(nb::Error::Other(err)) => Err(err), + } + } +} + +impl From> for NonBlocking { + fn from(v: Option) -> Self { + match v { + Some(v) => NonBlocking::Ready(v), + None => NonBlocking::WouldBlock, + } + } +} + +impl From> for nb::Result { + fn from(v: NonBlocking) -> Self { + match v { + NonBlocking::Ready(v) => Ok(v), + NonBlocking::WouldBlock => Err(nb::Error::WouldBlock), + } + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum Request { + Read, + Write(u8), + Flush, +} + +pub(crate) type Response = Result; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum SuccessResponse { + Read(NonBlocking), + Write(NonBlocking<()>), + Flush(NonBlocking<()>), +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum ErrorResponse { + WriteError, + FlushError, +} diff --git a/crates/sel4-hal-adapters/src/smoltcp/mod.rs b/crates/sel4-microkit/driver-adapters/src/serial/mod.rs similarity index 56% rename from crates/sel4-hal-adapters/src/smoltcp/mod.rs rename to crates/sel4-microkit/driver-adapters/src/serial/mod.rs index a23e92dd2..a87bbfb09 100644 --- a/crates/sel4-hal-adapters/src/smoltcp/mod.rs +++ b/crates/sel4-microkit/driver-adapters/src/serial/mod.rs @@ -5,4 +5,9 @@ // SPDX-License-Identifier: BSD-2-Clause // -pub mod phy; +mod message_types; + +pub mod client; +pub mod driver; + +pub use message_types::ErrorResponse; diff --git a/crates/sel4-microkit/driver-adapters/src/timer/client.rs b/crates/sel4-microkit/driver-adapters/src/timer/client.rs new file mode 100644 index 000000000..93797a02c --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/timer/client.rs @@ -0,0 +1,83 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::time::Duration; + +use sel4_driver_interfaces::timer::{Clock, ErrorType, NumTimers, Timers}; +use sel4_microkit::{Channel, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Client { + channel: Channel, +} + +impl Client { + pub fn new(channel: Channel) -> Self { + Client { channel } + } + + fn request(&self, req: Request) -> Result { + self.channel + .pp_call(MessageInfo::send_using_postcard(req).unwrap()) + .recv_using_postcard::() + .map_err(|_| Error::InvalidResponse)? + .map_err(Error::ErrorResponse) + } +} + +impl ErrorType for Client { + type Error = Error; +} + +impl Clock for Client { + fn get_time(&mut self) -> Result { + match self.request(Request::GetTime)? { + SuccessResponse::GetTime(v) => Ok(v), + _ => Err(Error::UnexpectedResponse), + } + } +} + +impl Timers for Client { + type TimerLayout = NumTimers; + + type Timer = usize; + + fn timer_layout(&mut self) -> Result { + match self.request(Request::NumTimers)? { + SuccessResponse::NumTimers(v) => Ok(NumTimers(v)), + _ => Err(Error::UnexpectedResponse), + } + } + + fn set_timeout_on( + &mut self, + timer: Self::Timer, + relative: Duration, + ) -> Result<(), Self::Error> { + match self.request(Request::SetTimeout { timer, relative })? { + SuccessResponse::SetTimeout => Ok(()), + _ => Err(Error::UnexpectedResponse), + } + } + + fn clear_timeout_on(&mut self, timer: Self::Timer) -> Result<(), Self::Error> { + match self.request(Request::ClearTimeout { timer })? { + SuccessResponse::ClearTimeout => Ok(()), + _ => Err(Error::UnexpectedResponse), + } + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Error { + ErrorResponse(ErrorResponse), + InvalidResponse, + UnexpectedResponse, +} diff --git a/crates/sel4-microkit/driver-adapters/src/timer/driver.rs b/crates/sel4-microkit/driver-adapters/src/timer/driver.rs new file mode 100644 index 000000000..78026336f --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/timer/driver.rs @@ -0,0 +1,103 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::convert::Infallible; + +use sel4_driver_interfaces::timer::{NumTimers, Timers}; +use sel4_driver_interfaces::HandleInterrupt; +use sel4_microkit::{Channel, Handler, MessageInfo}; +use sel4_microkit_message::MessageInfoExt; + +use super::message_types::*; + +#[derive(Clone, Debug)] +pub struct HandlerImpl { + driver: Driver, + timer: Channel, + client: Channel, + num_timers: usize, +} + +impl> HandlerImpl { + pub fn new(mut driver: Driver, timer: Channel, client: Channel) -> Result { + let num_timers = driver.timer_layout()?.0; + Ok(Self { + driver, + timer, + client, + num_timers, + }) + } + + fn guard_timer(&self, timer: usize) -> Result<(), ErrorResponse> { + if timer < self.num_timers { + Ok(()) + } else { + Err(ErrorResponse::TimerOutOfBounds) + } + } +} + +impl Handler for HandlerImpl +where + Driver: Timers + HandleInterrupt, +{ + type Error = Infallible; + + fn notified(&mut self, channel: Channel) -> Result<(), Self::Error> { + if channel == self.timer { + self.driver.handle_interrupt(); + self.timer.irq_ack().unwrap(); + self.client.notify(); + } else { + panic!("unexpected channel: {channel:?}"); + } + Ok(()) + } + + fn protected( + &mut self, + channel: Channel, + msg_info: MessageInfo, + ) -> Result { + if channel == self.client { + Ok(match msg_info.recv_using_postcard::() { + Ok(req) => { + let resp = match req { + Request::GetTime => self + .driver + .get_time() + .map(SuccessResponse::GetTime) + .map_err(|_| ErrorResponse::Unspecified), + Request::NumTimers => self + .driver + .timer_layout() + .map(|NumTimers(n)| SuccessResponse::NumTimers(n)) + .map_err(|_| ErrorResponse::Unspecified), + Request::SetTimeout { timer, relative } => { + self.guard_timer(timer).and_then(|_| { + self.driver + .set_timeout_on(timer, relative) + .map(|_| SuccessResponse::SetTimeout) + .map_err(|_| ErrorResponse::Unspecified) + }) + } + Request::ClearTimeout { timer } => self.guard_timer(timer).and_then(|_| { + self.driver + .clear_timeout_on(timer) + .map(|_| SuccessResponse::ClearTimeout) + .map_err(|_| ErrorResponse::Unspecified) + }), + }; + MessageInfo::send_using_postcard(resp).unwrap() + } + Err(_) => MessageInfo::send_unspecified_error(), + }) + } else { + panic!("unexpected channel: {channel:?}"); + } + } +} diff --git a/crates/sel4-microkit/driver-adapters/src/timer/message_types.rs b/crates/sel4-microkit/driver-adapters/src/timer/message_types.rs new file mode 100644 index 000000000..7323143f5 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/timer/message_types.rs @@ -0,0 +1,32 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +use core::time::Duration; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum Request { + GetTime, + NumTimers, + SetTimeout { timer: usize, relative: Duration }, + ClearTimeout { timer: usize }, +} + +pub(crate) type Response = Result; + +#[derive(Debug, Serialize, Deserialize)] +pub(crate) enum SuccessResponse { + GetTime(Duration), + NumTimers(usize), + SetTimeout, + ClearTimeout, +} + +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub enum ErrorResponse { + TimerOutOfBounds, + Unspecified, +} diff --git a/crates/sel4-microkit/driver-adapters/src/timer/mod.rs b/crates/sel4-microkit/driver-adapters/src/timer/mod.rs new file mode 100644 index 000000000..5d29bcbd8 --- /dev/null +++ b/crates/sel4-microkit/driver-adapters/src/timer/mod.rs @@ -0,0 +1,12 @@ +// +// Copyright 2024, Colias Group, LLC +// +// SPDX-License-Identifier: BSD-2-Clause +// + +mod message_types; + +pub mod client; +pub mod driver; + +pub use message_types::ErrorResponse; diff --git a/crates/sel4-microkit/message/src/lib.rs b/crates/sel4-microkit/message/src/lib.rs index f5f7757cd..b78a2a0d4 100644 --- a/crates/sel4-microkit/message/src/lib.rs +++ b/crates/sel4-microkit/message/src/lib.rs @@ -15,8 +15,8 @@ use serde::{Deserialize, Serialize}; use sel4_microkit_base::{with_msg_bytes, with_msg_bytes_mut, MessageInfo, MessageRegisterValue}; use sel4_microkit_message_types::{ - EmptyMessage, MessageLabel, MessageRecv, MessageSend, MessageValueRecv, MessageValueSend, - TriviallyLabeled, TryFromDefaultMessageLabelError, + EmptyMessage, EmptyMessageValue, MessageLabel, MessageRecv, MessageSend, MessageValueRecv, + MessageValueSend, TriviallyLabeled, }; #[cfg(feature = "postcard")] @@ -24,14 +24,66 @@ use sel4_microkit_message_types::MessageValueUsingPostcard; pub use sel4_microkit_message_types as types; -pub const UNSPECIFIED_ERROR_LABEL: MessageLabel = (1 << MessageInfo::label_width()) - 1; +const MAX_MESSAGE_LABEL: MessageLabel = + !0 >> (mem::size_of::() * 8 - MessageInfo::label_width()); + +// // // + +pub const UNSPECIFIED_ERROR_MESSAGE_LABEL: MessageLabel = MAX_MESSAGE_LABEL; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct UnspecifiedErrorMessage; + +impl From> + for UnspecifiedErrorMessage +{ + fn from(_: TriviallyLabeled) -> Self { + Default::default() + } +} + +impl From + for TriviallyLabeled +{ + fn from(_: UnspecifiedErrorMessage) -> Self { + Default::default() + } +} + +impl MessageSend for UnspecifiedErrorMessage { + type Label = as MessageSend>::Label; + + type Error = as MessageSend>::Error; + + fn write_message(self, buf: &mut [u8]) -> Result<(Self::Label, usize), Self::Error> { + >::from(self) + .write_message(buf) + } +} + +impl MessageRecv for UnspecifiedErrorMessage { + type Label = as MessageRecv>::Label; + + type Error = as MessageRecv>::Error; + + fn read_message(label: Self::Label, buf: &[u8]) -> Result { + >::read_message( + label, buf, + ) + .map(Into::into) + } +} + +// // // pub trait MessageInfoExt: Sized { fn send(val: T) -> Result; fn recv(self) -> Result>; - fn send_unspecified_error() -> Self; + fn send_unspecified_error() -> Self { + Self::send(UnspecifiedErrorMessage).unwrap_or_else(|absurdity| match absurdity {}) + } fn send_empty() -> Self { Self::send(EmptyMessage).unwrap_or_else(|absurdity| match absurdity {}) @@ -42,13 +94,14 @@ pub trait MessageInfoExt: Sized { } fn send_with_trivial_label(val: T) -> Result { - Self::send(TriviallyLabeled(val)) + type Helper = TriviallyLabeled; // get default LABEL + Self::send(Helper::new(val)) } fn recv_with_trivial_label( self, ) -> Result>> { - self.recv().map(|TriviallyLabeled(val)| val) + self.recv().map(TriviallyLabeled::into_inner) } #[cfg(feature = "postcard")] @@ -61,13 +114,7 @@ pub trait MessageInfoExt: Sized { #[cfg(feature = "postcard")] fn recv_using_postcard Deserialize<'a>>( self, - ) -> Result< - T, - MessageRecvError< - TryFromDefaultMessageLabelError, - as MessageValueRecv>::Error, - >, - > { + ) -> Result>>> { self.recv_with_trivial_label() .map(|MessageValueUsingPostcard(val)| val) } @@ -77,14 +124,15 @@ impl MessageInfoExt for MessageInfo { fn send(val: T) -> Result { let (label, num_bytes) = with_msg_bytes_mut(|buf| val.write_message(buf))?; let label = label.into(); - assert!(label < UNSPECIFIED_ERROR_LABEL); // TODO return error instead? + assert!(label <= MAX_MESSAGE_LABEL); + // assert!(label != UNSPECIFIED_ERROR_MESSAGE_LABEL); Ok(Self::new(label, bytes_to_mrs(num_bytes))) } fn recv(self) -> Result> { - if self.label() >= UNSPECIFIED_ERROR_LABEL { - return Err(MessageRecvError::Unspecified); - } + // if self.label() == UNSPECIFIED_ERROR_MESSAGE_LABEL) { + // return Err(MessageRecvError::Unspecified); + // } let label = self .label() .try_into() @@ -93,9 +141,9 @@ impl MessageInfoExt for MessageInfo { .map_err(MessageRecvError::ValueError) } - fn send_unspecified_error() -> Self { - Self::new(UNSPECIFIED_ERROR_LABEL, 0) - } + // fn send_unspecified_error() -> Self { + // Self::new(UNSPECIFIED_ERROR_MESSAGE_LABEL, 0) + // } } pub type MessageRecvErrorFor = MessageRecvError< @@ -107,7 +155,7 @@ pub type MessageRecvErrorFor = MessageRecvError< pub enum MessageRecvError { LabelError(E1), ValueError(E2), - Unspecified, + // Unspecified, } impl fmt::Display for MessageRecvError { @@ -115,7 +163,7 @@ impl fmt::Display for MessageRecvError write!(f, "label error: {}", err), Self::ValueError(err) => write!(f, "value error: {}", err), - Self::Unspecified => write!(f, "unspecified error"), + // Self::Unspecified => write!(f, "unspecified error"), } } } diff --git a/crates/sel4-microkit/message/types/src/lib.rs b/crates/sel4-microkit/message/types/src/lib.rs index 0f926953c..9477f8840 100644 --- a/crates/sel4-microkit/message/types/src/lib.rs +++ b/crates/sel4-microkit/message/types/src/lib.rs @@ -55,142 +55,180 @@ pub trait MessageRecv: Sized { // // // -impl MessageValueSend for T { - type Error = SendAsBytesError; +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct EmptyMessageValue; - fn write_message_value(self, buf: &mut [u8]) -> Result { - self.write_to_prefix(buf) - .ok_or(SendAsBytesError::ValueTooLarge)?; - Ok(mem::size_of_val(&self)) +impl MessageValueSend for EmptyMessageValue { + type Error = Infallible; + + fn write_message_value(self, _buf: &mut [u8]) -> Result { + Ok(0) } } -impl MessageValueRecv for T { - type Error = RecvFromBytesError; +impl MessageValueRecv for EmptyMessageValue { + type Error = RecvEmptyMessageValueError; fn read_message_value(buf: &[u8]) -> Result { - Unalign::::read_from_prefix(buf) - .ok_or(RecvFromBytesError::MessageTooShort) - .map(|unalign| unalign.get()) + if buf.is_empty() { + Ok(Self) + } else { + Err(Self::Error::MessageIsNotEmpty) + } } } #[derive(Copy, Clone, Debug)] -pub enum SendAsBytesError { - ValueTooLarge, -} - -#[derive(Copy, Clone, Debug)] -pub enum RecvFromBytesError { - MessageTooShort, +pub enum RecvEmptyMessageValueError { + MessageIsNotEmpty, } // // // -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] -pub struct EmptyMessageValue; +#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)] +pub struct ConstMessageLabel(()); -impl MessageValueSend for EmptyMessageValue { - type Error = Infallible; +impl ConstMessageLabel