From 62452373ac9bc9b7adeefc19453fbb1cbcddc4f4 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Sun, 31 Dec 2023 20:16:51 +0800 Subject: [PATCH] services: start implementing services Signed-off-by: Sean Cross --- src/xous/definitions.rs | 55 ++++++++++++++++++++++++++ src/xous/services.rs | 36 +++++++++++++++++ src/xous/services/log.rs | 56 +++++++++++++++++++++++++++ src/xous/services/ticktimer.rs | 70 ++++++++++++++++++++++++++++++++++ 4 files changed, 217 insertions(+) create mode 100644 src/xous/services.rs create mode 100644 src/xous/services/log.rs create mode 100644 src/xous/services/ticktimer.rs diff --git a/src/xous/definitions.rs b/src/xous/definitions.rs index 2553dba..df661cb 100644 --- a/src/xous/definitions.rs +++ b/src/xous/definitions.rs @@ -1,5 +1,14 @@ #![allow(dead_code)] +#[derive(Debug, Copy, Clone)] +pub enum Message { + MutableBorrow = 0, + Borrow = 1, + Move = 2, + Scalar = 3, + BlockingScalar = 4, +} + #[derive(Debug, Copy, Clone)] pub enum SyscallResultNumber { Ok = 0, @@ -18,6 +27,7 @@ pub enum SyscallResultNumber { #[derive(Debug)] pub enum Syscall { Unknown([i64; 8]), + Yield, IncreaseHeap( i64, /* number of bytes to add */ i64, /* memory flags */ @@ -28,6 +38,27 @@ pub enum Syscall { i64, /* flags */ i64, /* name */ ), + Connect([u32; 4] /* Server ID */), + SendMessage( + u32, /* Connection ID */ + u32, /* message kind */ + u32, /* opcode */ + [u32; 4], /* descriptor */ + ), + UpdateMemoryFlags( + i64, /* address */ + i64, /* range */ + i64, /* flags */ + ), + CreateThread( + i64, /* entry point */ + i64, /* stack pointer */ + i64, /* stack length */ + i64, /* argument 1 */ + i64, /* argument 2 */ + i64, /* argument 3 */ + i64, /* argument 4 */ + ), } #[derive(Debug)] @@ -57,6 +88,30 @@ impl From<[i64; 8]> for Syscall { match value[0].into() { SyscallNumber::IncreaseHeap => Syscall::IncreaseHeap(value[1], value[2]), SyscallNumber::MapMemory => Syscall::MapMemory(value[1], value[2], value[3], value[4]), + SyscallNumber::Connect => Syscall::Connect([ + value[1] as u32, + value[2] as u32, + value[3] as u32, + value[4] as u32, + ]), + SyscallNumber::SendMessage => Syscall::SendMessage( + value[1] as u32, + value[2] as u32, + value[3] as u32, + [ + value[4] as u32, + value[5] as u32, + value[6] as u32, + value[7] as u32, + ], + ), + SyscallNumber::UpdateMemoryFlags => { + Syscall::UpdateMemoryFlags(value[1], value[2], value[3]) + } + SyscallNumber::CreateThread => Syscall::CreateThread( + value[1], value[2], value[3], value[4], value[5], value[6], value[7], + ), + SyscallNumber::Yield => Syscall::Yield, _ => Syscall::Unknown(value), } } diff --git a/src/xous/services.rs b/src/xous/services.rs new file mode 100644 index 0000000..73706be --- /dev/null +++ b/src/xous/services.rs @@ -0,0 +1,36 @@ +pub mod log; +pub mod ticktimer; + +pub enum ScalarResult { + Scalar1(u32), + Scalar2([u32; 2]), + Scalar5([u32; 5]), +} + +pub trait Service { + fn scalar(&mut self, sender: u32, opcode: u32, _args: [u32; 4]) { + panic!("Unknown scalar to service {}: {}", sender, opcode); + } + fn blocking_scalar(&mut self, sender: u32, opcode: u32, _args: [u32; 4]) -> ScalarResult { + panic!("Unknown scalar to service {}: {}", sender, opcode); + } + fn lend(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) -> [u32; 2] { + panic!("Unknown lend to service {}: {} ({:?})", sender, opcode, extra); + } + fn lend_mut(&mut self, sender: u32, opcode: u32, _buf: &mut [u8], extra: [u32; 2]) -> [u32; 2] { + panic!("Unknown lend_mut to service {}: {} ({:?})", sender, opcode, extra); + } + fn send(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) { + panic!("Unknown send to service {}: {} ({:?})", sender, opcode, extra); + } +} + +pub fn get_service(name: &[u32; 4]) -> Option> { + match name { + [0x6b636974, 0x656d6974, 0x65732d72, 0x72657672] => { + Some(Box::new(ticktimer::Ticktimer::new())) + } + [0x73756f78, 0x676f6c2d, 0x7265732d, 0x20726576] => Some(Box::new(log::Log::new())), + _ => None, + } +} diff --git a/src/xous/services/log.rs b/src/xous/services/log.rs new file mode 100644 index 0000000..29b8fe3 --- /dev/null +++ b/src/xous/services/log.rs @@ -0,0 +1,56 @@ +use super::{ScalarResult, Service}; +use std::io::Write; + +enum LogLendOpcode { + /// A `&[u8]` destined for stdout + StandardOutput = 1, + + /// A `&[u8]` destined for stderr + StandardError = 2, +} + +pub struct Log {} + +impl Log { + pub fn new() -> Self { + // println!("Constructing a log server"); + Log {} + } +} + +impl Default for Log { + fn default() -> Self { + Self::new() + } +} + +impl Service for Log { + fn scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) { + println!("Log scalar {}: {} {:x?}", sender, opcode, args); + } + fn blocking_scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) -> ScalarResult { + println!("Log blocking_scalar {}: {} {:x?}", sender, opcode, args); + ScalarResult::Scalar1(0) + } + fn lend(&mut self, sender: u32, opcode: u32, buf: &[u8], extra: [u32; 2]) -> [u32; 2] { + if opcode == LogLendOpcode::StandardOutput as u32 { + let print_buffer = &buf[0..extra[1] as usize]; + // println!("Log stdout:"); + std::io::stdout().write_all(print_buffer).unwrap(); + } else if opcode == LogLendOpcode::StandardError as u32 { + let print_buffer = &buf[0..extra[1] as usize]; + // println!("Log stderr:"); + std::io::stderr().write_all(print_buffer).unwrap(); + } else { + panic!("Log lend {}: {} {:x?}", sender, opcode, buf); + } + [0, 0] + } + fn lend_mut(&mut self, sender: u32, opcode: u32, _buf: &mut [u8], extra: [u32; 2]) -> [u32; 2] { + println!("Log lend_mut {}: {} {:x?}", sender, opcode, extra); + [0, 0] + } + fn send(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) { + println!("Log send {}: {} {:x?}", sender, opcode, extra); + } +} diff --git a/src/xous/services/ticktimer.rs b/src/xous/services/ticktimer.rs new file mode 100644 index 0000000..b93d7bd --- /dev/null +++ b/src/xous/services/ticktimer.rs @@ -0,0 +1,70 @@ +pub struct Ticktimer { + start: std::time::SystemTime, +} + +enum ScalarOpcode { + ElapsedMs = 0, + WaitForCondition = 8 +} + +impl Ticktimer { + pub fn new() -> Self { + // println!("Constructing a ticktimer"); + Ticktimer { + start: std::time::SystemTime::now(), + } + } +} + +impl Default for Ticktimer { + fn default() -> Self { + Self::new() + } +} + +impl super::Service for Ticktimer { + fn scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) { + println!("Ticktimer scalar {}: {} {:x?}", sender, opcode, args); + } + fn blocking_scalar(&mut self, sender: u32, opcode: u32, args: [u32; 4]) -> super::ScalarResult { + if opcode == ScalarOpcode::ElapsedMs as u32 { + let elapsed_ms = std::time::SystemTime::now() + .duration_since(self.start) + .unwrap() + .as_millis() as u64; + super::ScalarResult::Scalar2([elapsed_ms as u32, (elapsed_ms >> 32) as u32]) + } else if opcode == ScalarOpcode::WaitForCondition as u32 { + let start = std::time::SystemTime::now(); + let mut elapsed_ms = start + .duration_since(self.start) + .unwrap() + .as_millis() as u64; + let mut condition = args[0]; + while condition != 0 { + std::thread::sleep(std::time::Duration::from_millis(1)); + elapsed_ms = start + .duration_since(self.start) + .unwrap() + .as_millis() as u64; + condition = args[0]; + } + super::ScalarResult::Scalar2([elapsed_ms as u32, (elapsed_ms >> 32) as u32]) + } else { + panic!( + "Ticktimer blocking_scalar {}: {} {:x?}", + sender, opcode, args + ); + } + } + fn lend(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) -> [u32; 2] { + println!("Ticktimer lend {}: {} {:x?}", sender, opcode, extra); + [0, 0] + } + fn lend_mut(&mut self, sender: u32, opcode: u32, _buf: &mut [u8], extra: [u32; 2]) -> [u32; 2] { + println!("Ticktimer lend_mut {}: {} {:x?}", sender, opcode, extra); + [0, 0] + } + fn send(&mut self, sender: u32, opcode: u32, _buf: &[u8], extra: [u32; 2]) { + println!("Ticktimer send {}: {} {:x?}", sender, opcode, extra); + } +}