summaryrefslogtreecommitdiffstats
path: root/library/std/src/os/xous/ffi
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /library/std/src/os/xous/ffi
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/std/src/os/xous/ffi')
-rw-r--r--library/std/src/os/xous/ffi/definitions.rs283
-rw-r--r--library/std/src/os/xous/ffi/definitions/memoryflags.rs176
2 files changed, 459 insertions, 0 deletions
diff --git a/library/std/src/os/xous/ffi/definitions.rs b/library/std/src/os/xous/ffi/definitions.rs
new file mode 100644
index 000000000..345005bcc
--- /dev/null
+++ b/library/std/src/os/xous/ffi/definitions.rs
@@ -0,0 +1,283 @@
+mod memoryflags;
+pub(crate) use memoryflags::*;
+
+#[stable(feature = "rust1", since = "1.0.0")]
+/// Indicates a particular syscall number as used by the Xous kernel.
+#[derive(Copy, Clone)]
+#[repr(usize)]
+pub enum Syscall {
+ MapMemory = 2,
+ Yield = 3,
+ UpdateMemoryFlags = 12,
+ ReceiveMessage = 15,
+ SendMessage = 16,
+ Connect = 17,
+ CreateThread = 18,
+ UnmapMemory = 19,
+ ReturnMemory = 20,
+ TerminateProcess = 22,
+ TrySendMessage = 24,
+ TryConnect = 25,
+ GetThreadId = 32,
+ JoinThread = 36,
+ AdjustProcessLimit = 38,
+ ReturnScalar = 40,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+/// Copies of these invocation types here for when we're running
+/// in environments without libxous.
+#[derive(Copy, Clone)]
+#[repr(usize)]
+pub enum SyscallResult {
+ Ok = 0,
+ Error = 1,
+ MemoryRange = 3,
+ ConnectionId = 7,
+ Message = 9,
+ ThreadId = 10,
+ Scalar1 = 14,
+ Scalar2 = 15,
+ MemoryReturned = 18,
+ Scalar5 = 20,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Copy, Clone)]
+/// A list of all known errors that may be returned by the Xous kernel.
+#[repr(usize)]
+pub enum Error {
+ NoError = 0,
+ BadAlignment = 1,
+ BadAddress = 2,
+ OutOfMemory = 3,
+ MemoryInUse = 4,
+ InterruptNotFound = 5,
+ InterruptInUse = 6,
+ InvalidString = 7,
+ ServerExists = 8,
+ ServerNotFound = 9,
+ ProcessNotFound = 10,
+ ProcessNotChild = 11,
+ ProcessTerminated = 12,
+ Timeout = 13,
+ InternalError = 14,
+ ServerQueueFull = 15,
+ ThreadNotAvailable = 16,
+ UnhandledSyscall = 17,
+ InvalidSyscall = 18,
+ ShareViolation = 19,
+ InvalidThread = 20,
+ InvalidPid = 21,
+ UnknownError = 22,
+ AccessDenied = 23,
+ UseBeforeInit = 24,
+ DoubleFree = 25,
+ DebugInProgress = 26,
+ InvalidLimit = 27,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<usize> for Error {
+ fn from(src: usize) -> Self {
+ match src {
+ 0 => Self::NoError,
+ 1 => Self::BadAlignment,
+ 2 => Self::BadAddress,
+ 3 => Self::OutOfMemory,
+ 4 => Self::MemoryInUse,
+ 5 => Self::InterruptNotFound,
+ 6 => Self::InterruptInUse,
+ 7 => Self::InvalidString,
+ 8 => Self::ServerExists,
+ 9 => Self::ServerNotFound,
+ 10 => Self::ProcessNotFound,
+ 11 => Self::ProcessNotChild,
+ 12 => Self::ProcessTerminated,
+ 13 => Self::Timeout,
+ 14 => Self::InternalError,
+ 15 => Self::ServerQueueFull,
+ 16 => Self::ThreadNotAvailable,
+ 17 => Self::UnhandledSyscall,
+ 18 => Self::InvalidSyscall,
+ 19 => Self::ShareViolation,
+ 20 => Self::InvalidThread,
+ 21 => Self::InvalidPid,
+ 23 => Self::AccessDenied,
+ 24 => Self::UseBeforeInit,
+ 25 => Self::DoubleFree,
+ 26 => Self::DebugInProgress,
+ 27 => Self::InvalidLimit,
+ 22 | _ => Self::UnknownError,
+ }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<i32> for Error {
+ fn from(src: i32) -> Self {
+ let Ok(src) = core::convert::TryInto::<usize>::try_into(src) else {
+ return Self::UnknownError;
+ };
+ src.into()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::Display for Error {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ write!(
+ f,
+ "{}",
+ match self {
+ Error::NoError => "no error occurred",
+ Error::BadAlignment => "memory was not properly aligned",
+ Error::BadAddress => "an invalid address was supplied",
+ Error::OutOfMemory => "the process or service has run out of memory",
+ Error::MemoryInUse => "the requested address is in use",
+ Error::InterruptNotFound =>
+ "the requested interrupt does not exist on this platform",
+ Error::InterruptInUse => "the requested interrupt is currently in use",
+ Error::InvalidString => "the specified string was not formatted correctly",
+ Error::ServerExists => "a server with that address already exists",
+ Error::ServerNotFound => "the requetsed server could not be found",
+ Error::ProcessNotFound => "the target process does not exist",
+ Error::ProcessNotChild =>
+ "the requested operation can only be done on child processes",
+ Error::ProcessTerminated => "the target process has crashed",
+ Error::Timeout => "the requested operation timed out",
+ Error::InternalError => "an internal error occurred",
+ Error::ServerQueueFull => "the server has too many pending messages",
+ Error::ThreadNotAvailable => "the specified thread does not exist",
+ Error::UnhandledSyscall => "the kernel did not recognize that syscall",
+ Error::InvalidSyscall => "the syscall had incorrect parameters",
+ Error::ShareViolation => "an attempt was made to share memory twice",
+ Error::InvalidThread => "tried to resume a thread that was not ready",
+ Error::InvalidPid => "kernel attempted to use a pid that was not valid",
+ Error::AccessDenied => "no permission to perform the requested operation",
+ Error::UseBeforeInit => "attempt to use a service before initialization finished",
+ Error::DoubleFree => "the requested resource was freed twice",
+ Error::DebugInProgress => "kernel attempted to activate a thread being debugged",
+ Error::InvalidLimit => "process attempted to adjust an invalid limit",
+ Error::UnknownError => "an unknown error occurred",
+ }
+ )
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::Debug for Error {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ write!(f, "{}", self)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl crate::error::Error for Error {}
+
+/// Indicates the type of Message that is sent when making a `SendMessage` syscall.
+#[derive(Copy, Clone)]
+#[repr(usize)]
+pub(crate) enum InvokeType {
+ LendMut = 1,
+ Lend = 2,
+ Move = 3,
+ Scalar = 4,
+ BlockingScalar = 5,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug, Copy, Clone)]
+/// A representation of a connection to a Xous service.
+pub struct Connection(u32);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl From<u32> for Connection {
+ fn from(src: u32) -> Connection {
+ Connection(src)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl TryFrom<usize> for Connection {
+ type Error = core::num::TryFromIntError;
+ fn try_from(src: usize) -> Result<Self, Self::Error> {
+ Ok(Connection(src.try_into()?))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Into<u32> for Connection {
+ fn into(self) -> u32 {
+ self.0
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl TryInto<usize> for Connection {
+ type Error = core::num::TryFromIntError;
+ fn try_into(self) -> Result<usize, Self::Error> {
+ self.0.try_into()
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[derive(Debug)]
+pub enum ServerAddressError {
+ InvalidLength,
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct ServerAddress([u32; 4]);
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl TryFrom<&str> for ServerAddress {
+ type Error = ServerAddressError;
+ fn try_from(value: &str) -> Result<Self, Self::Error> {
+ let b = value.as_bytes();
+ if b.len() == 0 || b.len() > 16 {
+ return Err(Self::Error::InvalidLength);
+ }
+
+ let mut this_temp = [0u8; 16];
+ for (dest, src) in this_temp.iter_mut().zip(b.iter()) {
+ *dest = *src;
+ }
+
+ let mut this = [0u32; 4];
+ for (dest, src) in this.iter_mut().zip(this_temp.chunks_exact(4)) {
+ *dest = u32::from_le_bytes(src.try_into().unwrap());
+ }
+ Ok(ServerAddress(this))
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Into<[u32; 4]> for ServerAddress {
+ fn into(self) -> [u32; 4] {
+ self.0
+ }
+}
+
+#[derive(Debug, Copy, Clone)]
+pub(crate) struct ThreadId(usize);
+
+impl From<usize> for ThreadId {
+ fn from(src: usize) -> ThreadId {
+ ThreadId(src)
+ }
+}
+
+impl Into<usize> for ThreadId {
+ fn into(self) -> usize {
+ self.0
+ }
+}
+
+#[derive(Copy, Clone)]
+#[repr(usize)]
+/// Limits that can be passed to `AdjustLimit`
+pub(crate) enum Limits {
+ HeapMaximum = 1,
+ HeapSize = 2,
+}
diff --git a/library/std/src/os/xous/ffi/definitions/memoryflags.rs b/library/std/src/os/xous/ffi/definitions/memoryflags.rs
new file mode 100644
index 000000000..af9de3cbf
--- /dev/null
+++ b/library/std/src/os/xous/ffi/definitions/memoryflags.rs
@@ -0,0 +1,176 @@
+/// Flags to be passed to the MapMemory struct.
+/// Note that it is an error to have memory be
+/// writable and not readable.
+#[derive(Copy, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Debug)]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub struct MemoryFlags {
+ bits: usize,
+}
+
+impl MemoryFlags {
+ /// Free this memory
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub const FREE: Self = Self { bits: 0b0000_0000 };
+
+ /// Immediately allocate this memory. Otherwise it will
+ /// be demand-paged. This is implicitly set when `phys`
+ /// is not 0.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub const RESERVE: Self = Self { bits: 0b0000_0001 };
+
+ /// Allow the CPU to read from this page.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub const R: Self = Self { bits: 0b0000_0010 };
+
+ /// Allow the CPU to write to this page.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub const W: Self = Self { bits: 0b0000_0100 };
+
+ /// Allow the CPU to execute from this page.
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub const X: Self = Self { bits: 0b0000_1000 };
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn bits(&self) -> usize {
+ self.bits
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn from_bits(raw: usize) -> Option<MemoryFlags> {
+ if raw > 16 { None } else { Some(MemoryFlags { bits: raw }) }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn is_empty(&self) -> bool {
+ self.bits == 0
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn empty() -> MemoryFlags {
+ MemoryFlags { bits: 0 }
+ }
+
+ #[stable(feature = "rust1", since = "1.0.0")]
+ pub fn all() -> MemoryFlags {
+ MemoryFlags { bits: 15 }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::Binary for MemoryFlags {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ core::fmt::Binary::fmt(&self.bits, f)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::Octal for MemoryFlags {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ core::fmt::Octal::fmt(&self.bits, f)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::LowerHex for MemoryFlags {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ core::fmt::LowerHex::fmt(&self.bits, f)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::fmt::UpperHex for MemoryFlags {
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
+ core::fmt::UpperHex::fmt(&self.bits, f)
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitOr for MemoryFlags {
+ type Output = Self;
+
+ /// Returns the union of the two sets of flags.
+ #[inline]
+ fn bitor(self, other: MemoryFlags) -> Self {
+ Self { bits: self.bits | other.bits }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitOrAssign for MemoryFlags {
+ /// Adds the set of flags.
+ #[inline]
+ fn bitor_assign(&mut self, other: Self) {
+ self.bits |= other.bits;
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitXor for MemoryFlags {
+ type Output = Self;
+
+ /// Returns the left flags, but with all the right flags toggled.
+ #[inline]
+ fn bitxor(self, other: Self) -> Self {
+ Self { bits: self.bits ^ other.bits }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitXorAssign for MemoryFlags {
+ /// Toggles the set of flags.
+ #[inline]
+ fn bitxor_assign(&mut self, other: Self) {
+ self.bits ^= other.bits;
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitAnd for MemoryFlags {
+ type Output = Self;
+
+ /// Returns the intersection between the two sets of flags.
+ #[inline]
+ fn bitand(self, other: Self) -> Self {
+ Self { bits: self.bits & other.bits }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::BitAndAssign for MemoryFlags {
+ /// Disables all flags disabled in the set.
+ #[inline]
+ fn bitand_assign(&mut self, other: Self) {
+ self.bits &= other.bits;
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::Sub for MemoryFlags {
+ type Output = Self;
+
+ /// Returns the set difference of the two sets of flags.
+ #[inline]
+ fn sub(self, other: Self) -> Self {
+ Self { bits: self.bits & !other.bits }
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::SubAssign for MemoryFlags {
+ /// Disables all flags enabled in the set.
+ #[inline]
+ fn sub_assign(&mut self, other: Self) {
+ self.bits &= !other.bits;
+ }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl core::ops::Not for MemoryFlags {
+ type Output = Self;
+
+ /// Returns the complement of this set of flags.
+ #[inline]
+ fn not(self) -> Self {
+ Self { bits: !self.bits } & MemoryFlags { bits: 15 }
+ }
+}