diff --git a/xous-rs/src/definitions.rs b/xous-rs/src/definitions.rs index 5870d167a..4896e2498 100644 --- a/xous-rs/src/definitions.rs +++ b/xous-rs/src/definitions.rs @@ -12,6 +12,9 @@ pub type Connection = usize; /// Server ID pub type SID = (usize, usize, usize, usize); +/// Connection ID +pub type CID = usize; + /// Equivalent to a RISC-V Hart ID pub type CpuID = usize; @@ -43,30 +46,34 @@ pub struct Context { } #[repr(C)] +#[derive(Debug)] pub struct MemoryMessage { - id: MessageId, - in_buf: Option, - in_buf_size: Option, - out_buf: Option, - out_buf_size: Option, + pub id: MessageId, + pub in_buf: Option, + pub in_buf_size: Option, + pub out_buf: Option, + pub out_buf_size: Option, } #[repr(C)] +#[derive(Debug)] pub struct ScalarMessage { - id: MessageId, - arg1: usize, - arg2: usize, - arg3: usize, - arg4: usize, + pub id: MessageId, + pub arg1: usize, + pub arg2: usize, + pub arg3: usize, + pub arg4: usize, } #[repr(usize)] +#[derive(Debug)] pub enum Message { Memory(MemoryMessage), Scalar(ScalarMessage), } #[repr(C)] +#[derive(Debug)] pub struct MessageEnvelope { sender: MessageSender, message: Message, diff --git a/xous-rs/src/syscall.rs b/xous-rs/src/syscall.rs index 815982923..dab1740f4 100644 --- a/xous-rs/src/syscall.rs +++ b/xous-rs/src/syscall.rs @@ -1,4 +1,7 @@ -use crate::{CpuID, Error, MemoryAddress, PID, SID, MessageEnvelope}; +use crate::{ + CpuID, Error, MemoryAddress, MemoryMessage, MemorySize, Message, MessageEnvelope, + ScalarMessage, CID, PID, SID, +}; use num_derive::FromPrimitive; use num_traits::FromPrimitive; @@ -240,6 +243,13 @@ pub enum SysCall { /// be created. CreateServer(usize /* server name */), + /// Connect to a server. This turns a 128-bit Serever ID into a 32-bit + /// Connection ID. + Connect(SID /* server id */), + + /// Send a message to a server + SendMessage(CID, Message), + /// This syscall does not exist Invalid(usize, usize, usize, usize, usize, usize, usize), } @@ -259,6 +269,8 @@ enum SysCallNumber { SetMemRegion = 13, CreateServer = 14, WaitMessage = 15, + SendMessage = 16, + Connect = 17, Invalid, } @@ -285,7 +297,16 @@ impl SysCall { ], SysCall::Yield => [SysCallNumber::Yield as usize, 0, 0, 0, 0, 0, 0, 0], SysCall::WaitEvent => [SysCallNumber::WaitEvent as usize, 0, 0, 0, 0, 0, 0, 0], - SysCall::WaitMessage(sid) => [SysCallNumber::WaitMessage as usize, sid.0, sid.1, sid.2, sid.3, 0, 0, 0], + SysCall::WaitMessage(sid) => [ + SysCallNumber::WaitMessage as usize, + sid.0, + sid.1, + sid.2, + sid.3, + 0, + 0, + 0, + ], SysCall::Suspend(a1, a2) => [ SysCallNumber::Suspend as usize, a1 as usize, @@ -360,7 +381,34 @@ impl SysCall { 0, ], - SysCall::CreateServer(a1) => [SysCallNumber::CreateServer as usize, a1, 0, 0, 0, 0, 0, 0], + SysCall::CreateServer(a1) => { + [SysCallNumber::CreateServer as usize, a1, 0, 0, 0, 0, 0, 0] + }, + SysCall::Connect(sid) => { + [SysCallNumber::Connect as usize, sid.0, sid.1, sid.2, sid.3, 0, 0, 0] + } + SysCall::SendMessage(a1, ref a2) => match a2 { + Message::Memory(mm) => [ + SysCallNumber::SendMessage as usize, + a1, + 1, + mm.id as usize, + mm.in_buf.map(|x| x.get()).unwrap_or(0) as usize, + mm.in_buf_size.map(|x| x.get()).unwrap_or(0) as usize, + mm.out_buf.map(|x| x.get()).unwrap_or(0) as usize, + mm.out_buf_size.map(|x| x.get()).unwrap_or(0) as usize, + ], + Message::Scalar(sc) => [ + SysCallNumber::SendMessage as usize, + a1, + 2, + sc.id as usize, + sc.arg1, + sc.arg2, + sc.arg3, + sc.arg4, + ], + }, SysCall::Invalid(a1, a2, a3, a4, a5, a6, a7) => { [SysCallNumber::Invalid as usize, a1, a2, a3, a4, a5, a6, a7] } @@ -406,6 +454,53 @@ impl SysCall { SysCall::SetMemRegion(a1 as PID, MemoryType::from(a2), a3 as *mut usize, a4) } Some(SysCallNumber::CreateServer) => SysCall::CreateServer(a1), + Some(SysCallNumber::Connect) => SysCall::Connect((a1, a2, a3, a4)), + Some(SysCallNumber::SendMessage) => match a2 { + 1 => SysCall::SendMessage( + a1, + Message::Memory(MemoryMessage { + id: a3, + in_buf: MemoryAddress::new(a4), + in_buf_size: MemorySize::new(a5), + out_buf: MemoryAddress::new(a6), + out_buf_size: MemorySize::new(a7), + }), + ), + 2 => SysCall::SendMessage( + a1, + Message::Scalar(ScalarMessage { + id: a3, + arg1: a4, + arg2: a5, + arg3: a6, + arg4: a7, + }), + ), + _ => SysCall::Invalid(a1, a2, a3, a4, a5, a6, a7), + }, + + // SysCall::SendMessage(a1, ref a2) => match a2 { + // Message::Memory(mm) => [ + // SysCallNumber::SendMessage as usize, + // a1, + // 1, + // mm.id as usize, + // mm.in_buf.map(|x| x.get()).unwrap_or(0) as usize, + // mm.in_buf_size.map(|x| x.get()).unwrap_or(0) as usize, + // mm.out_buf.map(|x| x.get()).unwrap_or(0) as usize, + // mm.out_buf_size.map(|x| x.get()).unwrap_or(0) as usize, + // ], + // Message::Scalar(sc) => [ + // SysCallNumber::SendMessage as usize, + // a1, + // 2, + // sc.id as usize, + // sc.arg1, + // sc.arg2, + // sc.arg3, + // sc.arg4, + // ], + // }, Some(SysCallNumber::Invalid) => SysCall::Invalid(a1, a2, a3, a4, a5, a6, a7), None => return Err(InvalidSyscall {}), }) @@ -524,8 +619,21 @@ pub fn create_server(name: usize) -> core::result::Result { /// /// # Errors /// -pub fn receive_message(sid: SID) -> core::result::Result { - rsyscall(SysCall::WaitMessage(sid)).expect("Couldn't call watimessage"); +pub fn receive_message(server: SID) -> core::result::Result { + let result = rsyscall(SysCall::WaitMessage(server)).expect("Couldn't call watimessage"); + Err(Error::UnhandledSyscall) +} + +/// Send a message to a server. This thread will block until the message is responded to. +/// If the message type is `Memory`, then the memory addresses pointed to will be +/// unavailable to this process until this function returns. +/// +/// # Errors +/// +/// * **ServerNotFound**: The server does not exist so the connection is now invalid +/// * **BadAddress**: The client tried to pass a Memory message using an address it doesn't own +/// * **Timeout**: The timeout limit has been reached +pub fn send_message(server: SID, message: MessageEnvelope) -> core::result::Result<(), Error> { Err(Error::UnhandledSyscall) }