From 5766c6f7f72ef76a99dcd6b177caa88bd6f7d589 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Sun, 18 Oct 2026 13:13:53 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20extract=20ports/drivers/bins=20laye?= =?UTF-8?q?rs=20=E2=80=94=20clean=20dependency=20inversion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Separate abstractions from implementations following DIP: servers/ drivers/ │ │ ▼ ▼ ports/ (trait-only crates, zero deps) New crates: ports/ (abstractions): - port-framebuffer: Framebuffer trait - port-block-device: BlockDevice trait + SectorId - port-input-device: InputDevice trait + InputEvent types drivers/ (implementations depend on ports/): - driver-framebuffer-virtio: VirtIO GPU framebuffer - driver-framebuffer-mock: test double - driver-block-virtio: VirtIO block device bins/ (composition roots wire server + driver): - display-qemu: DisplayServer - storage-qemu: storage server with VirtIO block Servers no longer own their hardware traits or driver code. Neither server nor driver depends on the other — both point inward to the port abstraction. --- Cargo.lock | 60 +++++++++++++++- Cargo.toml | 18 +++++ Makefile | 5 +- crates/bins/display-qemu/Cargo.toml | 16 +++++ crates/bins/display-qemu/src/main.rs | 14 ++++ crates/bins/storage-qemu/Cargo.toml | 13 ++++ .../storage-qemu}/src/main.rs | 0 crates/drivers/block/virtio/Cargo.toml | 7 ++ .../block/virtio/src/lib.rs} | 72 ++++--------------- crates/drivers/framebuffer/mock/Cargo.toml | 7 ++ .../framebuffer/mock/src/lib.rs} | 13 ++-- crates/drivers/framebuffer/virtio/Cargo.toml | 7 ++ .../framebuffer/virtio/src/lib.rs} | 38 ++++------ crates/ports/block-device/Cargo.toml | 6 ++ .../block-device/src/lib.rs} | 2 + crates/ports/framebuffer/Cargo.toml | 6 ++ .../framebuffer/src/lib.rs} | 2 + crates/ports/input-device/Cargo.toml | 6 ++ crates/ports/input-device/src/lib.rs | 54 ++++++++++++++ crates/servers/display-server/Cargo.toml | 15 ++-- .../display-server/src/adapters/mod.rs | 2 - crates/servers/display-server/src/lib.rs | 14 ---- crates/servers/display-server/src/main.rs | 9 --- crates/servers/display-server/src/server.rs | 2 +- .../display-server/src/tests/server.rs | 2 +- crates/servers/input-server/Cargo.toml | 1 + .../servers/input-server/src/adapters/mock.rs | 3 +- .../input-server/src/adapters/qemu_uart.rs | 3 +- .../servers/input-server/src/input_device.rs | 7 +- crates/servers/input-server/src/protocol.rs | 53 +------------- crates/servers/storage-server/Cargo.toml | 12 +--- .../storage-server/src/adapters/mock_block.rs | 2 +- .../storage-server/src/adapters/mod.rs | 1 - crates/servers/storage-server/src/fs/ext4.rs | 2 +- crates/servers/storage-server/src/fs/fat16.rs | 2 +- crates/servers/storage-server/src/lib.rs | 5 +- .../servers/storage-server/src/tests/ext4.rs | 2 +- .../servers/storage-server/src/tests/fat16.rs | 2 +- scripts/make-disk-image.sh | 4 +- 39 files changed, 272 insertions(+), 217 deletions(-) create mode 100644 crates/bins/display-qemu/Cargo.toml create mode 100644 crates/bins/display-qemu/src/main.rs create mode 100644 crates/bins/storage-qemu/Cargo.toml rename crates/{servers/storage-server => bins/storage-qemu}/src/main.rs (100%) create mode 100644 crates/drivers/block/virtio/Cargo.toml rename crates/{servers/storage-server/src/adapters/virtio_blk.rs => drivers/block/virtio/src/lib.rs} (63%) create mode 100644 crates/drivers/framebuffer/mock/Cargo.toml rename crates/{servers/display-server/src/adapters/mock.rs => drivers/framebuffer/mock/src/lib.rs} (89%) create mode 100644 crates/drivers/framebuffer/virtio/Cargo.toml rename crates/{servers/display-server/src/adapters/qemu_virtio.rs => drivers/framebuffer/virtio/src/lib.rs} (86%) create mode 100644 crates/ports/block-device/Cargo.toml rename crates/{servers/storage-server/src/block_device.rs => ports/block-device/src/lib.rs} (97%) create mode 100644 crates/ports/framebuffer/Cargo.toml rename crates/{servers/display-server/src/framebuffer.rs => ports/framebuffer/src/lib.rs} (95%) create mode 100644 crates/ports/input-device/Cargo.toml create mode 100644 crates/ports/input-device/src/lib.rs delete mode 100644 crates/servers/display-server/src/adapters/mod.rs delete mode 100644 crates/servers/display-server/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index da460ff..bdf01a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,14 +49,25 @@ version = "0.1.0" name = "contacts-server" version = "0.1.0" +[[package]] +name = "display-qemu" +version = "0.1.0" +dependencies = [ + "display-server", + "driver-framebuffer-virtio", + "server-framework", + "userspace", + "userspace-rt", +] + [[package]] name = "display-server" version = "0.1.0" dependencies = [ + "driver-framebuffer-mock", + "port-framebuffer", "server-framework", "types", - "userspace", - "userspace-rt", ] [[package]] @@ -66,6 +77,27 @@ dependencies = [ "types", ] +[[package]] +name = "driver-block-virtio" +version = "0.1.0" +dependencies = [ + "port-block-device", +] + +[[package]] +name = "driver-framebuffer-mock" +version = "0.1.0" +dependencies = [ + "port-framebuffer", +] + +[[package]] +name = "driver-framebuffer-virtio" +version = "0.1.0" +dependencies = [ + "port-framebuffer", +] + [[package]] name = "echo" version = "0.1.0" @@ -107,6 +139,7 @@ dependencies = [ name = "input-server" version = "0.1.0" dependencies = [ + "port-input-device", "server-framework", "types", "userspace", @@ -170,6 +203,18 @@ dependencies = [ "types", ] +[[package]] +name = "port-block-device" +version = "0.1.0" + +[[package]] +name = "port-framebuffer" +version = "0.1.0" + +[[package]] +name = "port-input-device" +version = "0.1.0" + [[package]] name = "power-server" version = "0.1.0" @@ -205,14 +250,23 @@ dependencies = [ "userspace-rt", ] +[[package]] +name = "storage-qemu" +version = "0.1.0" +dependencies = [ + "storage-server", + "userspace-rt", +] + [[package]] name = "storage-server" version = "0.1.0" dependencies = [ + "driver-block-virtio", + "port-block-device", "server-framework", "types", "userspace", - "userspace-rt", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 6e71fbd..27cd478 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,6 +41,14 @@ members = [ "crates/types", "crates/userspace", "crates/userspace-rt", + "crates/ports/framebuffer", + "crates/ports/block-device", + "crates/ports/input-device", + "crates/drivers/framebuffer/virtio", + "crates/drivers/framebuffer/mock", + "crates/drivers/block/virtio", + "crates/bins/display-qemu", + "crates/bins/storage-qemu", ] resolver = "2" @@ -84,6 +92,16 @@ telephony-server = { path = "crates/servers/telephony-server" } usb-server = { path = "crates/servers/usb-server" } user-manager = { path = "crates/servers/user-manager" } +# ports +port-framebuffer = { path = "crates/ports/framebuffer" } +port-block-device = { path = "crates/ports/block-device" } +port-input-device = { path = "crates/ports/input-device" } + +# drivers +driver-framebuffer-virtio = { path = "crates/drivers/framebuffer/virtio" } +driver-framebuffer-mock = { path = "crates/drivers/framebuffer/mock" } +driver-block-virtio = { path = "crates/drivers/block/virtio" } + # apps snake = { path = "crates/apps/snake" } diff --git a/Makefile b/Makefile index 1828f86..5ec342f 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,10 @@ kani-kernel: kani: kani-types kani-domain kani-kernel build: - cargo build -p adapter-riscv --target $(RISCV_TARGET) --release + cargo build --target $(RISCV_TARGET) --release \ + -p adapter-riscv -p init -p echo -p snake \ + -p display-qemu -p storage-qemu \ + -p input-server -p log-server -p permission-manager -p session-server image: build scripts/make-disk-image.sh diff --git a/crates/bins/display-qemu/Cargo.toml b/crates/bins/display-qemu/Cargo.toml new file mode 100644 index 0000000..9a49984 --- /dev/null +++ b/crates/bins/display-qemu/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "display-qemu" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "display-qemu" +test = false +bench = false + +[dependencies] +userspace-rt = { workspace = true } +userspace = { workspace = true } +server-framework = { workspace = true } +display-server = { workspace = true } +driver-framebuffer-virtio = { workspace = true } diff --git a/crates/bins/display-qemu/src/main.rs b/crates/bins/display-qemu/src/main.rs new file mode 100644 index 0000000..dee2f07 --- /dev/null +++ b/crates/bins/display-qemu/src/main.rs @@ -0,0 +1,14 @@ +#![no_std] +#![no_main] + +extern crate userspace_rt; + +use driver_framebuffer_virtio::VirtioFramebuffer; + +#[unsafe(no_mangle)] +extern "C" fn main() { + let fb = VirtioFramebuffer::new(); + let mut srv = display_server::server::DisplayServer::new(fb); + server_framework::serve(&mut srv, 0); + loop { userspace::syscall::yield_now(); } +} diff --git a/crates/bins/storage-qemu/Cargo.toml b/crates/bins/storage-qemu/Cargo.toml new file mode 100644 index 0000000..a99e70a --- /dev/null +++ b/crates/bins/storage-qemu/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "storage-qemu" +version = "0.1.0" +edition = "2024" + +[[bin]] +name = "storage-qemu" +test = false +bench = false + +[dependencies] +userspace-rt = { workspace = true } +storage-server = { workspace = true } diff --git a/crates/servers/storage-server/src/main.rs b/crates/bins/storage-qemu/src/main.rs similarity index 100% rename from crates/servers/storage-server/src/main.rs rename to crates/bins/storage-qemu/src/main.rs diff --git a/crates/drivers/block/virtio/Cargo.toml b/crates/drivers/block/virtio/Cargo.toml new file mode 100644 index 0000000..2b17753 --- /dev/null +++ b/crates/drivers/block/virtio/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "driver-block-virtio" +version = "0.1.0" +edition = "2024" + +[dependencies] +port-block-device = { workspace = true } diff --git a/crates/servers/storage-server/src/adapters/virtio_blk.rs b/crates/drivers/block/virtio/src/lib.rs similarity index 63% rename from crates/servers/storage-server/src/adapters/virtio_blk.rs rename to crates/drivers/block/virtio/src/lib.rs index b767c0c..09ad723 100644 --- a/crates/servers/storage-server/src/adapters/virtio_blk.rs +++ b/crates/drivers/block/virtio/src/lib.rs @@ -1,4 +1,6 @@ -use crate::block_device::{BlockDevice, SectorId}; +#![no_std] + +use port_block_device::{BlockDevice, SectorId}; const QUEUE_SIZE: usize = 8; const SECTOR_SIZE: usize = 512; @@ -6,9 +8,6 @@ const SECTOR_SIZE: usize = 512; const MMIO_BASE: usize = 0x20000; const VQUEUE_VA: usize = 0x21000; const REQ_HDR_VA: usize = 0x23000; - -// Physical addresses are written to a known location by the adapter at boot -// Layout at 0x24000: [req_hdr_pa: u64, status_pa: u64, sector_buf_pa: u64] const PHYS_INFO_VA: usize = 0x24000; #[repr(C)] @@ -49,33 +48,15 @@ struct VirtioBlkReqHeader { sector: u64, } -fn mmio_read(offset: usize) -> u32 { - unsafe { core::ptr::read_volatile((MMIO_BASE + offset) as *const u32) } -} - fn mmio_write(offset: usize, val: u32) { unsafe { core::ptr::write_volatile((MMIO_BASE + offset) as *mut u32, val) } } -fn descs() -> *mut VirtqDesc { - VQUEUE_VA as *mut VirtqDesc -} - -fn avail() -> *mut VirtqAvail { - (VQUEUE_VA + QUEUE_SIZE * 16) as *mut VirtqAvail -} - -fn used() -> *mut VirtqUsed { - (VQUEUE_VA + 0x1000) as *mut VirtqUsed -} - -fn req_header() -> *mut VirtioBlkReqHeader { - REQ_HDR_VA as *mut VirtioBlkReqHeader -} - -fn req_status() -> *mut u8 { - (REQ_HDR_VA + 16) as *mut u8 -} +fn descs() -> *mut VirtqDesc { VQUEUE_VA as *mut VirtqDesc } +fn avail() -> *mut VirtqAvail { (VQUEUE_VA + QUEUE_SIZE * 16) as *mut VirtqAvail } +fn used() -> *mut VirtqUsed { (VQUEUE_VA + 0x1000) as *mut VirtqUsed } +fn req_header() -> *mut VirtioBlkReqHeader { REQ_HDR_VA as *mut VirtioBlkReqHeader } +fn req_status() -> *mut u8 { (REQ_HDR_VA + 16) as *mut u8 } struct PhysAddrs { req_hdr: u64, @@ -105,18 +86,12 @@ impl VirtioBlockDevice { } impl BlockDevice for VirtioBlockDevice { - fn sector_size(&self) -> usize { - SECTOR_SIZE - } - - fn sector_count(&self) -> usize { - 0xFFFF - } + fn sector_size(&self) -> usize { SECTOR_SIZE } + fn sector_count(&self) -> usize { 0xFFFF } fn read_sector(&mut self, sector: SectorId, buf: &mut [u8]) -> bool { if buf.len() < SECTOR_SIZE { return false; } - // Write to the local VA — device reads via physical address unsafe { let hdr = req_header(); (*hdr).req_type = 0; @@ -125,28 +100,12 @@ impl BlockDevice for VirtioBlockDevice { core::ptr::write_volatile(req_status(), 0xFF); - // Sector buffer: use a fixed area at REQ_HDR_VA + 32 let sector_buf_va = (REQ_HDR_VA + 32) as *mut u8; let d = descs(); - (*d.add(0)) = VirtqDesc { - addr: self.phys.req_hdr, - len: 16, - flags: 1, - next: 1, - }; - (*d.add(1)) = VirtqDesc { - addr: self.phys.sector_buf, - len: SECTOR_SIZE as u32, - flags: 2 | 1, - next: 2, - }; - (*d.add(2)) = VirtqDesc { - addr: self.phys.status, - len: 1, - flags: 2, - next: 0, - }; + (*d.add(0)) = VirtqDesc { addr: self.phys.req_hdr, len: 16, flags: 1, next: 1 }; + (*d.add(1)) = VirtqDesc { addr: self.phys.sector_buf, len: SECTOR_SIZE as u32, flags: 2 | 1, next: 2 }; + (*d.add(2)) = VirtqDesc { addr: self.phys.status, len: 1, flags: 2, next: 0 }; let a = avail(); let avail_idx = core::ptr::read_volatile(&(*a).idx); @@ -166,11 +125,8 @@ impl BlockDevice for VirtioBlockDevice { if timeout == 0 { return false; } } - if core::ptr::read_volatile(req_status()) != 0 { - return false; - } + if core::ptr::read_volatile(req_status()) != 0 { return false; } - // Copy from sector buffer VA to caller's buffer core::ptr::copy_nonoverlapping(sector_buf_va, buf.as_mut_ptr(), SECTOR_SIZE); } diff --git a/crates/drivers/framebuffer/mock/Cargo.toml b/crates/drivers/framebuffer/mock/Cargo.toml new file mode 100644 index 0000000..26fe110 --- /dev/null +++ b/crates/drivers/framebuffer/mock/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "driver-framebuffer-mock" +version = "0.1.0" +edition = "2024" + +[dependencies] +port-framebuffer = { workspace = true } diff --git a/crates/servers/display-server/src/adapters/mock.rs b/crates/drivers/framebuffer/mock/src/lib.rs similarity index 89% rename from crates/servers/display-server/src/adapters/mock.rs rename to crates/drivers/framebuffer/mock/src/lib.rs index 09b9110..2511143 100644 --- a/crates/servers/display-server/src/adapters/mock.rs +++ b/crates/drivers/framebuffer/mock/src/lib.rs @@ -1,4 +1,6 @@ -use crate::framebuffer::Framebuffer; +#![no_std] + +use port_framebuffer::Framebuffer; pub struct MockFramebuffer { width: u16, @@ -33,13 +35,8 @@ impl MockFramebuffer { } impl Framebuffer for MockFramebuffer { - fn width(&self) -> u16 { - self.width - } - - fn height(&self) -> u16 { - self.height - } + fn width(&self) -> u16 { self.width } + fn height(&self) -> u16 { self.height } fn write_pixel(&mut self, x: u16, y: u16, color: u32) { if self.pixel_count < self.pixels.len() { diff --git a/crates/drivers/framebuffer/virtio/Cargo.toml b/crates/drivers/framebuffer/virtio/Cargo.toml new file mode 100644 index 0000000..ab885e3 --- /dev/null +++ b/crates/drivers/framebuffer/virtio/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "driver-framebuffer-virtio" +version = "0.1.0" +edition = "2024" + +[dependencies] +port-framebuffer = { workspace = true } diff --git a/crates/servers/display-server/src/adapters/qemu_virtio.rs b/crates/drivers/framebuffer/virtio/src/lib.rs similarity index 86% rename from crates/servers/display-server/src/adapters/qemu_virtio.rs rename to crates/drivers/framebuffer/virtio/src/lib.rs index 9efa4ab..6ca6f30 100644 --- a/crates/servers/display-server/src/adapters/qemu_virtio.rs +++ b/crates/drivers/framebuffer/virtio/src/lib.rs @@ -1,4 +1,6 @@ -use crate::framebuffer::Framebuffer; +#![no_std] + +use port_framebuffer::Framebuffer; const GPU_MMIO_VA: usize = 0x20000; const VQUEUE_VA: usize = 0x21000; @@ -11,7 +13,6 @@ const QUEUE_SIZE: usize = 8; struct PhysInfo { cmd_pa: u64, resp_pa: u64, - fb_pa: u64, width: u64, height: u64, } @@ -22,7 +23,6 @@ fn read_phys_info() -> PhysInfo { PhysInfo { cmd_pa: core::ptr::read_volatile(p), resp_pa: core::ptr::read_volatile(p.add(1)), - fb_pa: core::ptr::read_volatile(p.add(2)), width: core::ptr::read_volatile(p.add(3)), height: core::ptr::read_volatile(p.add(4)), } @@ -41,12 +41,11 @@ pub struct VirtioFramebuffer { } impl VirtioFramebuffer { - pub fn new(_buffer_addr: usize) -> Self { + pub fn new() -> Self { let phys = read_phys_info(); let width = phys.width as u16; let height = phys.height as u16; let stride = width as usize * FB_BPP; - Self { width, height, stride, phys } } @@ -55,13 +54,13 @@ impl VirtioFramebuffer { let desc0 = VQUEUE_VA as *mut u8; core::ptr::write_volatile(desc0 as *mut u64, self.phys.cmd_pa); core::ptr::write_volatile(desc0.add(8) as *mut u32, cmd_len); - core::ptr::write_volatile(desc0.add(12) as *mut u16, 1); // NEXT + core::ptr::write_volatile(desc0.add(12) as *mut u16, 1); core::ptr::write_volatile(desc0.add(14) as *mut u16, 1); let desc1 = desc0.add(16); core::ptr::write_volatile(desc1 as *mut u64, self.phys.resp_pa); core::ptr::write_volatile(desc1.add(8) as *mut u32, resp_len); - core::ptr::write_volatile(desc1.add(12) as *mut u16, 2); // WRITE + core::ptr::write_volatile(desc1.add(12) as *mut u16, 2); core::ptr::write_volatile(desc1.add(14) as *mut u16, 0); let avail = VQUEUE_VA + QUEUE_SIZE * 16; @@ -88,54 +87,41 @@ impl VirtioFramebuffer { } fn transfer_and_flush(&self, x: u32, y: u32, w: u32, h: u32) { - // TRANSFER_TO_HOST_2D unsafe { let p = CMDBUF_VA as *mut u8; core::ptr::write_bytes(p, 0, 512); - core::ptr::write_volatile(p as *mut u32, 0x0105); // TRANSFER_TO_HOST_2D - // rect at offset 24 + core::ptr::write_volatile(p as *mut u32, 0x0105); core::ptr::write_volatile(p.add(24) as *mut u32, x); core::ptr::write_volatile(p.add(28) as *mut u32, y); core::ptr::write_volatile(p.add(32) as *mut u32, w); core::ptr::write_volatile(p.add(36) as *mut u32, h); - // offset at 40 core::ptr::write_volatile(p.add(40) as *mut u64, 0); - // resource_id at 48 core::ptr::write_volatile(p.add(48) as *mut u32, 1); } self.send_gpu_cmd(56, 24); - // RESOURCE_FLUSH unsafe { let p = CMDBUF_VA as *mut u8; core::ptr::write_bytes(p, 0, 512); - core::ptr::write_volatile(p as *mut u32, 0x0106); // RESOURCE_FLUSH + core::ptr::write_volatile(p as *mut u32, 0x0106); core::ptr::write_volatile(p.add(24) as *mut u32, x); core::ptr::write_volatile(p.add(28) as *mut u32, y); core::ptr::write_volatile(p.add(32) as *mut u32, w); core::ptr::write_volatile(p.add(36) as *mut u32, h); - core::ptr::write_volatile(p.add(40) as *mut u32, 1); // resource_id + core::ptr::write_volatile(p.add(40) as *mut u32, 1); } self.send_gpu_cmd(48, 24); } } impl Framebuffer for VirtioFramebuffer { - fn width(&self) -> u16 { - self.width - } - - fn height(&self) -> u16 { - self.height - } + fn width(&self) -> u16 { self.width } + fn height(&self) -> u16 { self.height } fn write_pixel(&mut self, x: u16, y: u16, color: u32) { if x >= self.width || y >= self.height { return; } let offset = (y as usize) * self.stride + (x as usize) * FB_BPP; - let buf = FB_VA + offset; - unsafe { - core::ptr::write_volatile(buf as *mut u32, color); - } + unsafe { core::ptr::write_volatile((FB_VA + offset) as *mut u32, color); } } fn fill_rect(&mut self, x: u16, y: u16, w: u16, h: u16, color: u32) { diff --git a/crates/ports/block-device/Cargo.toml b/crates/ports/block-device/Cargo.toml new file mode 100644 index 0000000..a55553b --- /dev/null +++ b/crates/ports/block-device/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "port-block-device" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/crates/servers/storage-server/src/block_device.rs b/crates/ports/block-device/src/lib.rs similarity index 97% rename from crates/servers/storage-server/src/block_device.rs rename to crates/ports/block-device/src/lib.rs index 9e5fb21..fa4ae11 100644 --- a/crates/servers/storage-server/src/block_device.rs +++ b/crates/ports/block-device/src/lib.rs @@ -1,3 +1,5 @@ +#![no_std] + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct SectorId(u32); diff --git a/crates/ports/framebuffer/Cargo.toml b/crates/ports/framebuffer/Cargo.toml new file mode 100644 index 0000000..9d547a6 --- /dev/null +++ b/crates/ports/framebuffer/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "port-framebuffer" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/crates/servers/display-server/src/framebuffer.rs b/crates/ports/framebuffer/src/lib.rs similarity index 95% rename from crates/servers/display-server/src/framebuffer.rs rename to crates/ports/framebuffer/src/lib.rs index d477eb3..c79c048 100644 --- a/crates/servers/display-server/src/framebuffer.rs +++ b/crates/ports/framebuffer/src/lib.rs @@ -1,3 +1,5 @@ +#![no_std] + pub trait Framebuffer { fn width(&self) -> u16; fn height(&self) -> u16; diff --git a/crates/ports/input-device/Cargo.toml b/crates/ports/input-device/Cargo.toml new file mode 100644 index 0000000..1a44a8b --- /dev/null +++ b/crates/ports/input-device/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "port-input-device" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/crates/ports/input-device/src/lib.rs b/crates/ports/input-device/src/lib.rs new file mode 100644 index 0000000..3b9c371 --- /dev/null +++ b/crates/ports/input-device/src/lib.rs @@ -0,0 +1,54 @@ +#![no_std] + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Key { + Up, + Down, + Left, + Right, + Enter, + Escape, + Space, + Backspace, + Tab, + Char(u8), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum GamepadButton { + South, + East, + North, + West, + DpadUp, + DpadDown, + DpadLeft, + DpadRight, + Start, + Select, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Axis { + LeftX, + LeftY, + RightX, + RightY, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum InputEvent { + KeyDown(Key), + KeyUp(Key), + PointerDown { id: u8, x: u16, y: u16 }, + PointerMove { id: u8, x: u16, y: u16 }, + PointerUp { id: u8, x: u16, y: u16 }, + Scroll { dx: i16, dy: i16 }, + GamepadButton { button: GamepadButton, pressed: bool }, + GamepadAxis { axis: Axis, value: i16 }, +} + +pub trait InputDevice { + fn poll(&mut self) -> Option; + fn has_event(&self) -> bool; +} diff --git a/crates/servers/display-server/Cargo.toml b/crates/servers/display-server/Cargo.toml index 8639337..ec00464 100644 --- a/crates/servers/display-server/Cargo.toml +++ b/crates/servers/display-server/Cargo.toml @@ -3,17 +3,10 @@ name = "display-server" version = "0.1.0" edition = "2024" -[[bin]] -name = "display-server" -test = false -bench = false - -[features] -default = ["qemu-virt"] -qemu-virt = [] - [dependencies] types = { workspace = true } -userspace = { workspace = true } -userspace-rt = { workspace = true } server-framework = { workspace = true } +port-framebuffer = { workspace = true } + +[dev-dependencies] +driver-framebuffer-mock = { workspace = true } diff --git a/crates/servers/display-server/src/adapters/mod.rs b/crates/servers/display-server/src/adapters/mod.rs deleted file mode 100644 index b80b308..0000000 --- a/crates/servers/display-server/src/adapters/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod mock; -pub mod qemu_virtio; diff --git a/crates/servers/display-server/src/lib.rs b/crates/servers/display-server/src/lib.rs index 39ca638..08873ca 100644 --- a/crates/servers/display-server/src/lib.rs +++ b/crates/servers/display-server/src/lib.rs @@ -1,22 +1,8 @@ #![no_std] -pub mod adapters; -pub mod framebuffer; pub mod protocol; pub mod server; #[cfg(test)] #[path = "tests/mod.rs"] mod tests; - -pub fn run() -> ! { - #[cfg(feature = "qemu-virt")] - let fb = adapters::qemu_virtio::VirtioFramebuffer::new(0x10008000); - - #[cfg(not(feature = "qemu-virt"))] - let fb = adapters::mock::MockFramebuffer::new(320, 240); - - let mut srv = server::DisplayServer::new(fb); - server_framework::serve(&mut srv, 0); - loop { userspace::syscall::yield_now(); } -} diff --git a/crates/servers/display-server/src/main.rs b/crates/servers/display-server/src/main.rs deleted file mode 100644 index fef72f7..0000000 --- a/crates/servers/display-server/src/main.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![no_std] -#![no_main] - -extern crate userspace_rt; - -#[unsafe(no_mangle)] -extern "C" fn main() { - display_server::run(); -} diff --git a/crates/servers/display-server/src/server.rs b/crates/servers/display-server/src/server.rs index 279daae..32470bd 100644 --- a/crates/servers/display-server/src/server.rs +++ b/crates/servers/display-server/src/server.rs @@ -1,6 +1,6 @@ use server_framework::Server; -use crate::framebuffer::Framebuffer; +use port_framebuffer::Framebuffer; use crate::protocol::{DisplayRequest, DisplayResponse}; pub struct DisplayServer { diff --git a/crates/servers/display-server/src/tests/server.rs b/crates/servers/display-server/src/tests/server.rs index 891f522..3d87eb9 100644 --- a/crates/servers/display-server/src/tests/server.rs +++ b/crates/servers/display-server/src/tests/server.rs @@ -1,4 +1,4 @@ -use crate::adapters::mock::MockFramebuffer; +use driver_framebuffer_mock::MockFramebuffer; use crate::protocol::{DisplayRequest, DisplayResponse}; use crate::server::DisplayServer; use server_framework::Server; diff --git a/crates/servers/input-server/Cargo.toml b/crates/servers/input-server/Cargo.toml index e921cda..d097af9 100644 --- a/crates/servers/input-server/Cargo.toml +++ b/crates/servers/input-server/Cargo.toml @@ -17,3 +17,4 @@ types = { workspace = true } userspace = { workspace = true } userspace-rt = { workspace = true } server-framework = { workspace = true } +port-input-device = { workspace = true } diff --git a/crates/servers/input-server/src/adapters/mock.rs b/crates/servers/input-server/src/adapters/mock.rs index 3259fe0..6b79b41 100644 --- a/crates/servers/input-server/src/adapters/mock.rs +++ b/crates/servers/input-server/src/adapters/mock.rs @@ -1,5 +1,4 @@ -use crate::input_device::InputDevice; -use crate::protocol::InputEvent; +use crate::input_device::{InputDevice, InputEvent}; pub struct MockInputDevice { events: [Option; 16], diff --git a/crates/servers/input-server/src/adapters/qemu_uart.rs b/crates/servers/input-server/src/adapters/qemu_uart.rs index 8816266..7a402a5 100644 --- a/crates/servers/input-server/src/adapters/qemu_uart.rs +++ b/crates/servers/input-server/src/adapters/qemu_uart.rs @@ -1,5 +1,4 @@ -use crate::input_device::InputDevice; -use crate::protocol::{InputEvent, Key}; +use crate::input_device::{InputDevice, InputEvent, Key}; const UART_BASE: usize = 0x10000000; const UART_LSR: usize = 5; diff --git a/crates/servers/input-server/src/input_device.rs b/crates/servers/input-server/src/input_device.rs index 2f6db05..d4bd2c1 100644 --- a/crates/servers/input-server/src/input_device.rs +++ b/crates/servers/input-server/src/input_device.rs @@ -1,6 +1 @@ -use crate::protocol::InputEvent; - -pub trait InputDevice { - fn poll(&mut self) -> Option; - fn has_event(&self) -> bool; -} +pub use port_input_device::{InputDevice, InputEvent, Key, GamepadButton, Axis}; diff --git a/crates/servers/input-server/src/protocol.rs b/crates/servers/input-server/src/protocol.rs index 13ded6c..0ca118d 100644 --- a/crates/servers/input-server/src/protocol.rs +++ b/crates/servers/input-server/src/protocol.rs @@ -1,55 +1,5 @@ use server_framework::{Decode, Encode}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Key { - Up, - Down, - Left, - Right, - Enter, - Escape, - Space, - Backspace, - Tab, - Char(u8), -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum GamepadButton { - South, - East, - North, - West, - DpadUp, - DpadDown, - DpadLeft, - DpadRight, - Start, - Select, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Axis { - LeftX, - LeftY, - RightX, - RightY, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum InputEvent { - KeyDown(Key), - KeyUp(Key), - - PointerDown { id: u8, x: u16, y: u16 }, - PointerMove { id: u8, x: u16, y: u16 }, - PointerUp { id: u8, x: u16, y: u16 }, - - Scroll { dx: i16, dy: i16 }, - - GamepadButton { button: GamepadButton, pressed: bool }, - GamepadAxis { axis: Axis, value: i16 }, -} +pub use port_input_device::{Key, GamepadButton, Axis, InputEvent}; #[derive(Debug, PartialEq)] pub enum InputRequest { @@ -82,7 +32,6 @@ impl Decode for InputRequest { } } -// Event type tags for encoding const EV_KEY_DOWN: usize = 1; const EV_KEY_UP: usize = 2; const EV_PTR_DOWN: usize = 3; diff --git a/crates/servers/storage-server/Cargo.toml b/crates/servers/storage-server/Cargo.toml index f2eb7b4..5777a8d 100644 --- a/crates/servers/storage-server/Cargo.toml +++ b/crates/servers/storage-server/Cargo.toml @@ -3,17 +3,9 @@ name = "storage-server" version = "0.1.0" edition = "2024" -[[bin]] -name = "storage-server" -test = false -bench = false - -[features] -default = ["qemu-virt"] -qemu-virt = [] - [dependencies] types = { workspace = true } userspace = { workspace = true } -userspace-rt = { workspace = true } server-framework = { workspace = true } +port-block-device = { workspace = true } +driver-block-virtio = { workspace = true } diff --git a/crates/servers/storage-server/src/adapters/mock_block.rs b/crates/servers/storage-server/src/adapters/mock_block.rs index 3ccde2a..12cb897 100644 --- a/crates/servers/storage-server/src/adapters/mock_block.rs +++ b/crates/servers/storage-server/src/adapters/mock_block.rs @@ -1,4 +1,4 @@ -use crate::block_device::{BlockDevice, SectorId}; +use port_block_device::{BlockDevice, SectorId}; const SECTOR_SIZE: usize = 512; const MAX_SECTORS: usize = 64; diff --git a/crates/servers/storage-server/src/adapters/mod.rs b/crates/servers/storage-server/src/adapters/mod.rs index c1ff392..4eb8f1b 100644 --- a/crates/servers/storage-server/src/adapters/mod.rs +++ b/crates/servers/storage-server/src/adapters/mod.rs @@ -1,3 +1,2 @@ pub mod mock_block; pub mod mock_fs; -pub mod virtio_blk; diff --git a/crates/servers/storage-server/src/fs/ext4.rs b/crates/servers/storage-server/src/fs/ext4.rs index aff9a79..429d6c4 100644 --- a/crates/servers/storage-server/src/fs/ext4.rs +++ b/crates/servers/storage-server/src/fs/ext4.rs @@ -1,4 +1,4 @@ -use crate::block_device::{BlockDevice, SectorId}; +use port_block_device::{BlockDevice, SectorId}; use crate::filesystem::{DirEntry, FileHandle, FileName, FileSystem}; const SECTOR_SIZE: usize = 512; diff --git a/crates/servers/storage-server/src/fs/fat16.rs b/crates/servers/storage-server/src/fs/fat16.rs index b6d6096..94dbe25 100644 --- a/crates/servers/storage-server/src/fs/fat16.rs +++ b/crates/servers/storage-server/src/fs/fat16.rs @@ -1,4 +1,4 @@ -use crate::block_device::{BlockDevice, SectorId}; +use port_block_device::{BlockDevice, SectorId}; use crate::filesystem::{DirEntry, FileHandle, FileName, FileSystem}; const SECTOR_SIZE: usize = 512; diff --git a/crates/servers/storage-server/src/lib.rs b/crates/servers/storage-server/src/lib.rs index f847505..d453a23 100644 --- a/crates/servers/storage-server/src/lib.rs +++ b/crates/servers/storage-server/src/lib.rs @@ -1,7 +1,6 @@ #![no_std] pub mod adapters; -pub mod block_device; pub mod filesystem; pub mod fs; pub mod protocol; @@ -30,7 +29,7 @@ fn debug_print(s: &[u8]) { pub fn run() -> ! { debug_print(b"storage: started\n"); - let device = adapters::virtio_blk::VirtioBlockDevice::new(); + let device = driver_block_virtio::VirtioBlockDevice::new(); let fat16 = fs::fat16::Fat16::mount(device); if fat16.is_none() { debug_print(b"storage: FAT16 mount failed\n"); @@ -71,7 +70,7 @@ pub fn run() -> ! { } } -fn read_entire_file( +fn read_entire_file( fat: &mut fs::fat16::Fat16, filename: &[u8], out: &mut [u8], diff --git a/crates/servers/storage-server/src/tests/ext4.rs b/crates/servers/storage-server/src/tests/ext4.rs index 6848af5..1644105 100644 --- a/crates/servers/storage-server/src/tests/ext4.rs +++ b/crates/servers/storage-server/src/tests/ext4.rs @@ -1,5 +1,5 @@ use crate::adapters::mock_block::MockBlockDevice; -use crate::block_device::{BlockDevice, SectorId}; +use port_block_device::{BlockDevice, SectorId}; use crate::filesystem::{DirEntry, FileSystem}; use crate::fs::ext4::Ext4; diff --git a/crates/servers/storage-server/src/tests/fat16.rs b/crates/servers/storage-server/src/tests/fat16.rs index 938f711..eafccba 100644 --- a/crates/servers/storage-server/src/tests/fat16.rs +++ b/crates/servers/storage-server/src/tests/fat16.rs @@ -1,5 +1,5 @@ use crate::adapters::mock_block::MockBlockDevice; -use crate::block_device::{BlockDevice, SectorId}; +use port_block_device::{BlockDevice, SectorId}; use crate::filesystem::{DirEntry, FileSystem}; use crate::fs::fat16::Fat16; diff --git a/scripts/make-disk-image.sh b/scripts/make-disk-image.sh index fa8ce80..fefb503 100755 --- a/scripts/make-disk-image.sh +++ b/scripts/make-disk-image.sh @@ -24,11 +24,11 @@ copy() { copy init "init.elf" copy echo "echo.elf" copy snake "snake.elf" -copy display-server "display.elf" +copy display-qemu "display.elf" copy input-server "input.elf" copy log-server "log.elf" copy permission-manager "permis.elf" -copy storage-server "storage.elf" +copy storage-qemu "storage.elf" copy session-server "session.elf" echo ""