From 04ef7ff2756fdc4e3bf79213b10b82aa2bf6dec3 Mon Sep 17 00:00:00 2001 From: bunnie Date: Thu, 7 Mar 2024 20:09:47 +0800 Subject: [PATCH] create the swapper crate --- services/xous-swapper/Cargo.toml | 33 +++++++++++ services/xous-swapper/src/main.rs | 91 +++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 services/xous-swapper/Cargo.toml create mode 100644 services/xous-swapper/src/main.rs diff --git a/services/xous-swapper/Cargo.toml b/services/xous-swapper/Cargo.toml new file mode 100644 index 000000000..f394aee80 --- /dev/null +++ b/services/xous-swapper/Cargo.toml @@ -0,0 +1,33 @@ +[package] +authors = ["bunnie "] +description = "Xous microkernel OS inter-process name resolution server" +edition = "2018" +name = "xous-swapper" +version = "0.1.0" +license = "MIT OR Apache-2.0" +repository = "https://github.com/betrusted-io/xous-core/" +homepage = "https://betrusted.io/" + +# Dependency versions enforced by Cargo.lock. +[dependencies] +xous-api-names = "0.9.56" +log-server = { package = "xous-api-log", version = "0.1.54" } +xous = "0.9.58" +xous-ipc = "0.9.58" +num-derive = { version = "0.3.3", default-features = false } +num-traits = { version = "0.2.14", default-features = false } +log = "0.4.14" + +utralib = { version = "0.1.24", optional = true, default-features = false } + +[target.'cfg(any(windows,unix))'.dependencies] + +[features] +cramium-soc = ["utralib/cramium-soc"] +cramium-fpga = ["utralib/cramium-fpga"] +precursor = ["utralib/precursor"] +hosted = ["utralib/hosted"] +renode = ["utralib/renode"] +# for now, debug-print only works on Precursor targets +debug-print = ["precursor", "utralib/precursor"] +default = ["debug-print"] diff --git a/services/xous-swapper/src/main.rs b/services/xous-swapper/src/main.rs new file mode 100644 index 000000000..3a1bd4570 --- /dev/null +++ b/services/xous-swapper/src/main.rs @@ -0,0 +1,91 @@ +use core::fmt::{Error, Write}; + +use utralib::*; + +#[derive(Debug, num_derive::FromPrimitive, num_derive::ToPrimitive)] +#[repr(usize)] +pub enum Opcode { + /// Take the page lent to us, encrypt it and write it to swap + WriteToSwap = 0, + /// Find the requested page, decrypt it, and return it + ReadFromSwap = 1, + /// Kernel message advising us that a page of RAM was allocated + AllocateAdvisory = 2, + /// Kernel message requesting N pages to be swapped out. + Trim = 3, + /// Kernel message informing us that we have pages to free. + Free = 4, +} + +pub struct DebugUart { + #[cfg(feature = "debug-print")] + csr: CSR, +} +impl DebugUart { + #[cfg(feature = "debug-print")] + pub fn new() -> Self { + let debug_uart_mem = xous::syscall::map_memory( + xous::MemoryAddress::new(utra::app_uart::HW_APP_UART_BASE), + None, + 4096, + xous::MemoryFlags::R | xous::MemoryFlags::W, + ) + .expect("couldn't claim the debug UART"); + let debug_uart = CSR::new(debug_uart_mem.as_mut_ptr() as *mut u32); + + Self { csr: debug_uart } + } + + #[cfg(feature = "debug-print")] + pub fn putc(&mut self, c: u8) { + // Wait until TXFULL is `0` + while self.csr.r(utra::app_uart::TXFULL) != 0 {} + self.csr.wfo(utra::app_uart::RXTX_RXTX, c as u32); + } + + #[cfg(not(feature = "debug-print"))] + pub fn new() -> Self { Self {} } + + #[cfg(not(feature = "debug-print"))] + pub fn putc(&self, _c: u8) {} +} + +impl Write for DebugUart { + fn write_str(&mut self, s: &str) -> Result<(), Error> { + for c in s.bytes() { + self.putc(c); + } + Ok(()) + } +} + +fn main() { + // init the log, but this is mostly unused. + log_server::init_wait().unwrap(); + log::set_max_level(log::LevelFilter::Info); + log::info!("my PID is {}", xous::process::id()); + + // swapper is not allowed to use `log` for debugging under most circumstances, because + // the swapper can't send messages when handling a swap call. Instead, we use a local + // debug UART to handle this. This needs to be enabled with the "debug-print" feature + // and is mutually exclusive with the "gdb-stub" feature in the kernel since it uses + // the same physical hardware. + let mut duart = DebugUart::new(); + write!(duart, "Swapper started.\n\r"); + + let sid = xous::create_server().unwrap(); + loop { + let msg = xous::receive_message(shch_sid).unwrap(); + let op: Option = FromPrimitive::from_usize(msg.body.id()); + write!(duart, "Swapper got {:?}", msg); + match op { + Some(Opcode::WriteToSwap) => { + unimplemented!(); + } + // ... todo, other opcodes. + _ => { + write!(duart, "Unknown opcode {:?}", op); + } + } + } +}