mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
xous: add syscalls for connecting to a server
This is required because server IDs are 128 bits, but we only have enough space for 32 bits in the message. This is fine, because it means we can drop "Connect" permissions to prevent compromised clients from making new connections. Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
ebe3efc097
commit
19ddb32d9d
2 changed files with 130 additions and 15 deletions
|
|
@ -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<MemoryAddress>,
|
||||
in_buf_size: Option<MemorySize>,
|
||||
out_buf: Option<MemoryAddress>,
|
||||
out_buf_size: Option<MemorySize>,
|
||||
pub id: MessageId,
|
||||
pub in_buf: Option<MemoryAddress>,
|
||||
pub in_buf_size: Option<MemorySize>,
|
||||
pub out_buf: Option<MemoryAddress>,
|
||||
pub out_buf_size: Option<MemorySize>,
|
||||
}
|
||||
|
||||
#[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,
|
||||
|
|
|
|||
|
|
@ -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<SID, Error> {
|
|||
///
|
||||
/// # Errors
|
||||
///
|
||||
pub fn receive_message(sid: SID) -> core::result::Result<MessageEnvelope, Error> {
|
||||
rsyscall(SysCall::WaitMessage(sid)).expect("Couldn't call watimessage");
|
||||
pub fn receive_message(server: SID) -> core::result::Result<MessageEnvelope, Error> {
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue