diff --git a/src/sys/arm_compat/mod.rs b/src/sys/arm_compat/mod.rs index 7d83363..c1c1d41 100644 --- a/src/sys/arm_compat/mod.rs +++ b/src/sys/arm_compat/mod.rs @@ -13,7 +13,7 @@ pub(crate) mod errno; #[cfg(feature = "fs")] pub(crate) mod fs; -pub(crate) mod syscall; +pub mod syscall; use core::{ ffi::{c_void, CStr}, diff --git a/src/sys/arm_compat/syscall/aarch64.rs b/src/sys/arm_compat/syscall/aarch64.rs index e493d26..004a46b 100644 --- a/src/sys/arm_compat/syscall/aarch64.rs +++ b/src/sys/arm_compat/syscall/aarch64.rs @@ -11,13 +11,14 @@ macro_rules! trap { }; } +/// Raw semihosting call with a parameter that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { +pub unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { unsafe { let r; asm!( trap!(), - in("w0") number as u32, // OPERATION NUMBER REGISTER + in("w0") number.as_u32(), // OPERATION NUMBER REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // the PARAMETER REGISTER may be changed. inout("x1") parameter.0 => _, // PARAMETER REGISTER @@ -27,13 +28,15 @@ pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) RetReg(r) } } + +/// Raw semihosting call with a parameter that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { +pub unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { unsafe { let r; asm!( trap!(), - in("w0") number as u32, // OPERATION NUMBER REGISTER + in("w0") number.as_u32(), // OPERATION NUMBER REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // the PARAMETER REGISTER may be changed. inout("x1") parameter.0 => _, // PARAMETER REGISTER diff --git a/src/sys/arm_compat/syscall/arm.rs b/src/sys/arm_compat/syscall/arm.rs index a23656f..50fefe4 100644 --- a/src/sys/arm_compat/syscall/arm.rs +++ b/src/sys/arm_compat/syscall/arm.rs @@ -44,13 +44,14 @@ macro_rules! trap { // }; // } +/// Raw semihosting call with a parameter that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { +pub unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { unsafe { let r; asm!( trap!(), - inout("r0") number as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER + inout("r0") number.as_usize() => r, // OPERATION NUMBER REGISTER => RETURN REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // PARAMETER REGISTER may be changed. inout("r1") parameter.0 => _, // PARAMETER REGISTER @@ -59,13 +60,15 @@ pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) RetReg(r) } } + +/// Raw semihosting call with a parameter that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { +pub unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { unsafe { let r; asm!( trap!(), - inout("r0") number as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER + inout("r0") number.as_usize() => r, // OPERATION NUMBER REGISTER => RETURN REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // PARAMETER REGISTER may be changed. inout("r1") parameter.0 => _, // PARAMETER REGISTER diff --git a/src/sys/arm_compat/syscall/mod.rs b/src/sys/arm_compat/syscall/mod.rs index 4b588ea..3cdc58b 100644 --- a/src/sys/arm_compat/syscall/mod.rs +++ b/src/sys/arm_compat/syscall/mod.rs @@ -2,17 +2,15 @@ //! Raw semihosting call. -// TODO: should we expose this as public API of `sys` module? - #![allow(clippy::needless_pass_by_value)] -pub(crate) use arch::{syscall, syscall_readonly}; +pub use arch::{syscall, syscall_readonly}; #[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")] #[cfg_attr(target_arch = "arm", path = "arm.rs")] #[cfg_attr(any(target_arch = "riscv32", target_arch = "riscv64"), path = "riscv.rs")] mod arch; -pub(crate) use crate::sys::reg::{ParamRegR, ParamRegW, RetReg}; +pub use crate::sys::reg::{ParamRegR, ParamRegW, RetReg}; /// Semihosting operation numbers. /// @@ -20,70 +18,120 @@ pub(crate) use crate::sys::reg::{ParamRegR, ParamRegW, RetReg}; /// - `0x32-0xFF` Reserved for future use by ARM. /// - `0x100-0x1FF` Reserved for user applications. /// - `0x200-0xFFFFFFFF` Undefined and currently unused. -#[repr(u32)] -pub(crate) enum OperationNumber { +#[derive(Debug, Copy, Clone)] +#[non_exhaustive] +pub enum OperationNumber { /// [SYS_OPEN (0x01)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#612sys_open-0x01) - SYS_OPEN = 0x01, + SYS_OPEN, /// [SYS_CLOSE (0x02)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#62sys_close-0x02) - SYS_CLOSE = 0x02, + SYS_CLOSE, /// [SYS_WRITEC (0x03)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#623sys_writec-0x03) - SYS_WRITEC = 0x03, + SYS_WRITEC, /// [SYS_WRITE0 (0x04)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#624sys_write0-0x04) - SYS_WRITE0 = 0x04, + SYS_WRITE0, /// [SYS_WRITE (0x05)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#622sys_write-0x05) - SYS_WRITE = 0x05, + SYS_WRITE, /// [SYS_READ (0x06)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#613sys_read-0x06) - SYS_READ = 0x06, + SYS_READ, /// [SYS_READC (0x07)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#614sys_readc-0x07) - SYS_READC = 0x07, + SYS_READC, /// [SYS_ISERROR (0x08)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#610sys_iserror-0x08) - SYS_ISERROR = 0x08, + SYS_ISERROR, /// [SYS_ISTTY (0x09)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#611sys_istty-0x09) - SYS_ISTTY = 0x09, + SYS_ISTTY, /// [SYS_SEEK (0x0A)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#617sys_seek-0x0a) - SYS_SEEK = 0x0A, + SYS_SEEK, /// [SYS_FLEN (0x0C)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#67sys_flen-0x0c) - SYS_FLEN = 0x0C, + SYS_FLEN, // /// [SYS_TMPNAM (0x0D)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#621sys_tmpnam-0x0d) // #[deprecated = "tmpnam is deprecated as not secure on most host systems"] // SYS_TMPNAM = 0x0D, /// [SYS_REMOVE (0x0E)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#615sys_remove-0x0e) - SYS_REMOVE = 0x0E, + SYS_REMOVE, /// [SYS_RENAME (0x0F)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#616sys_rename-0x0f) - SYS_RENAME = 0x0F, + SYS_RENAME, /// [SYS_CLOCK (0x10)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#sys-clock-0x10) - SYS_CLOCK = 0x10, + SYS_CLOCK, /// [SYS_TIME (0x11)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#620sys_time-0x11) - SYS_TIME = 0x11, + SYS_TIME, /// [SYS_SYSTEM (0x12)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#618sys_system-0x12) - SYS_SYSTEM = 0x12, + SYS_SYSTEM, /// [SYS_ERRNO (0x13)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#64sys_errno-0x13) - SYS_ERRNO = 0x13, + SYS_ERRNO, /// [SYS_GET_CMDLINE (0x15)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#68sys_get_cmdline-0x15) - SYS_GET_CMDLINE = 0x15, + SYS_GET_CMDLINE, /// [SYS_HEAPINFO (0x16)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#69sys_heapinfo-0x16) - SYS_HEAPINFO = 0x16, + SYS_HEAPINFO, // #[deprecated = "obsoleted in semihosting specification version 2.0"] // angel_SWIreason_EnterSVC = 0x17, /// [SYS_EXIT (0x18)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#65sys_exit-0x18) #[doc(alias = "angel_SWIreason_ReportException")] // old name - SYS_EXIT = 0x18, + SYS_EXIT, // #[deprecated = "obsoleted in semihosting specification version 2.0"] // angelSWI_Reason_SyncCacheRange = 0x19, /// [SYS_EXIT_EXTENDED (0x20)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#66sys_exit_extended-0x20) // we use SYS_EXIT on 64-bit system because SYS_EXIT_EXTENDED is identical to the behavior of the mandatory SYS_EXIT. #[cfg_attr(target_pointer_width = "64", allow(dead_code))] - SYS_EXIT_EXTENDED = 0x20, + SYS_EXIT_EXTENDED, /// [SYS_ELAPSED (0x30)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#63sys_elapsed-0x30) - SYS_ELAPSED = 0x30, + SYS_ELAPSED, /// [SYS_TICKFREQ (0x31)](https://github.com/ARM-software/abi-aa/blob/HEAD/semihosting/semihosting.rst#619sys_tickfreq-0x31) - SYS_TICKFREQ = 0x31, + SYS_TICKFREQ, + + /// Some other (e.g. user defined) operation number + Other(u32), +} + +impl From for u32 { + fn from(op: OperationNumber) -> Self { + match op { + OperationNumber::SYS_OPEN => 0x01, + OperationNumber::SYS_CLOSE => 0x02, + OperationNumber::SYS_WRITEC => 0x03, + OperationNumber::SYS_WRITE0 => 0x04, + OperationNumber::SYS_WRITE => 0x05, + OperationNumber::SYS_READ => 0x06, + OperationNumber::SYS_READC => 0x07, + OperationNumber::SYS_ISERROR => 0x08, + OperationNumber::SYS_ISTTY => 0x09, + OperationNumber::SYS_SEEK => 0x0A, + OperationNumber::SYS_FLEN => 0x0C, + OperationNumber::SYS_REMOVE => 0x0E, + OperationNumber::SYS_RENAME => 0x0F, + OperationNumber::SYS_CLOCK => 0x10, + OperationNumber::SYS_TIME => 0x11, + OperationNumber::SYS_SYSTEM => 0x12, + OperationNumber::SYS_ERRNO => 0x13, + OperationNumber::SYS_GET_CMDLINE => 0x15, + OperationNumber::SYS_HEAPINFO => 0x16, + OperationNumber::SYS_EXIT => 0x18, + OperationNumber::SYS_EXIT_EXTENDED => 0x20, + OperationNumber::SYS_ELAPSED => 0x30, + OperationNumber::SYS_TICKFREQ => 0x31, + OperationNumber::Other(op) => op, + } + } } + +impl OperationNumber { + // Shortcut for >::into(op) + #[allow(dead_code)] + fn as_u32(self) -> u32 { + self.into() + } + + // Shortcut for >::into(op) as usize + #[allow(dead_code)] + fn as_usize(self) -> usize { + self.as_u32() as usize + } +} + pub(crate) use OperationNumber::*; /// `syscall_readonly(number, null)` #[inline] -pub(crate) unsafe fn syscall0(number: OperationNumber) -> RetReg { +pub unsafe fn syscall0(number: OperationNumber) -> RetReg { // In most operations that don't have parameters, such as SYS_ERRNO, and // SYS_CLOCK, the PARAMETER REGISTER must be zero. unsafe { syscall_readonly(number, ParamRegR::usize(0)) } diff --git a/src/sys/arm_compat/syscall/riscv.rs b/src/sys/arm_compat/syscall/riscv.rs index f9f75d4..c7d4a56 100644 --- a/src/sys/arm_compat/syscall/riscv.rs +++ b/src/sys/arm_compat/syscall/riscv.rs @@ -4,8 +4,9 @@ use core::arch::asm; use super::{OperationNumber, ParamRegR, ParamRegW, RetReg}; +/// Raw semihosting call with a parameter that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { +pub unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) -> RetReg { unsafe { let r; asm!( @@ -16,7 +17,7 @@ pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) "ebreak", "srai zero, zero, 0x7", ".option pop", - inout("a0") number as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER + inout("a0") number.as_usize() => r, // OPERATION NUMBER REGISTER => RETURN REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // PARAMETER REGISTER may be changed. inout("a1") parameter.0 => _, // PARAMETER REGISTER @@ -25,8 +26,10 @@ pub(crate) unsafe fn syscall(number: OperationNumber, parameter: ParamRegW<'_>) RetReg(r) } } + +/// Raw semihosting call with a parameter that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { +pub unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamRegR<'_>) -> RetReg { unsafe { let r; asm!( @@ -37,7 +40,7 @@ pub(crate) unsafe fn syscall_readonly(number: OperationNumber, parameter: ParamR "ebreak", "srai zero, zero, 0x7", ".option pop", - inout("a0") number as usize => r, // OPERATION NUMBER REGISTER => RETURN REGISTER + inout("a0") number.as_usize() => r, // OPERATION NUMBER REGISTER => RETURN REGISTER // Use inout because operation such as SYS_ELAPSED suggest that // PARAMETER REGISTER may be changed. inout("a1") parameter.0 => _, // PARAMETER REGISTER diff --git a/src/sys/mips/mod.rs b/src/sys/mips/mod.rs index b26a8b2..a1a53ac 100644 --- a/src/sys/mips/mod.rs +++ b/src/sys/mips/mod.rs @@ -11,7 +11,7 @@ pub(crate) mod errno; #[cfg(feature = "fs")] pub(crate) mod fs; -pub(crate) mod syscall; +pub mod syscall; use core::{ffi::CStr, mem}; diff --git a/src/sys/mips/syscall/mips.rs b/src/sys/mips/syscall/mips.rs index 99005af..358dd04 100644 --- a/src/sys/mips/syscall/mips.rs +++ b/src/sys/mips/syscall/mips.rs @@ -4,8 +4,9 @@ use core::arch::asm; use super::{OperationCode, ParamRegR, ParamRegW, RetReg}; +/// syscall with 0 arguments #[inline] -pub(crate) unsafe fn syscall0(op: OperationCode) -> (RetReg, RetReg) { +pub unsafe fn syscall0(op: OperationCode) -> (RetReg, RetReg) { unsafe { let r1; let r2; @@ -15,32 +16,16 @@ pub(crate) unsafe fn syscall0(op: OperationCode) -> (RetReg, RetReg) { out("$3") r2, out("$4") _, out("$5") _, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack, readonly), ); (RetReg(r1), RetReg(r2)) } } -// #[inline] -// pub(crate) unsafe fn syscall1(op: OperationCode, arg1: ParamRegW<'_>) -> (RetReg, RetReg) { -// unsafe { -// let r1; -// let r2; -// asm!( -// "sdbbp 1", -// inout("$2") 1_usize => r1, -// out("$3") r2, -// inout("$4") arg1.0 => _, -// out("$5") _, -// in("$25") op as usize, -// options(nostack), -// ); -// (RetReg(r1), RetReg(r2)) -// } -// } +/// Raw semihosting call with 1 parameter that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall1_readonly(op: OperationCode, arg1: ParamRegR<'_>) -> (RetReg, RetReg) { +pub unsafe fn syscall1(op: OperationCode, arg1: ParamRegW<'_>) -> (RetReg, RetReg) { unsafe { let r1; let r2; @@ -50,15 +35,35 @@ pub(crate) unsafe fn syscall1_readonly(op: OperationCode, arg1: ParamRegR<'_>) - out("$3") r2, inout("$4") arg1.0 => _, out("$5") _, - in("$25") op as usize, + in("$25") op.as_usize(), + options(nostack), + ); + (RetReg(r1), RetReg(r2)) + } +} + +/// Raw semihosting call with 1 parameter that will be read (but not modified) by the host +#[inline] +pub unsafe fn syscall1_readonly(op: OperationCode, arg1: ParamRegR<'_>) -> (RetReg, RetReg) { + unsafe { + let r1; + let r2; + asm!( + "sdbbp 1", + inout("$2") 1_usize => r1, + out("$3") r2, + inout("$4") arg1.0 => _, + out("$5") _, + in("$25") op.as_usize(), options(nostack, readonly), ); (RetReg(r1), RetReg(r2)) } } +/// Raw semihosting call with 2 parameters that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall2( +pub unsafe fn syscall2( op: OperationCode, arg1: ParamRegW<'_>, arg2: ParamRegW<'_>, @@ -72,14 +77,16 @@ pub(crate) unsafe fn syscall2( out("$3") r2, inout("$4") arg1.0 => _, inout("$5") arg2.0 => _, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack), ); (RetReg(r1), RetReg(r2)) } } + +/// Raw semihosting call with 2 parameters that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall2_readonly( +pub unsafe fn syscall2_readonly( op: OperationCode, arg1: ParamRegR<'_>, arg2: ParamRegR<'_>, @@ -93,15 +100,16 @@ pub(crate) unsafe fn syscall2_readonly( out("$3") r2, inout("$4") arg1.0 => _, inout("$5") arg2.0 => _, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack, readonly), ); (RetReg(r1), RetReg(r2)) } } +/// Raw semihosting call with 3 parameters that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall3( +pub unsafe fn syscall3( op: OperationCode, arg1: ParamRegW<'_>, arg2: ParamRegW<'_>, @@ -117,14 +125,16 @@ pub(crate) unsafe fn syscall3( inout("$4") arg1.0 => _, inout("$5") arg2.0 => _, in("$6") arg3.0, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack), ); (RetReg(r1), RetReg(r2)) } } + +/// Raw semihosting call with 3 parameters that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall3_readonly( +pub unsafe fn syscall3_readonly( op: OperationCode, arg1: ParamRegR<'_>, arg2: ParamRegR<'_>, @@ -140,15 +150,16 @@ pub(crate) unsafe fn syscall3_readonly( inout("$4") arg1.0 => _, inout("$5") arg2.0 => _, in("$6") arg3.0, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack, readonly), ); (RetReg(r1), RetReg(r2)) } } +/// Raw semihosting call with 4 parameters that will be read + modified by the host #[inline] -pub(crate) unsafe fn syscall4( +pub unsafe fn syscall4( op: OperationCode, arg1: ParamRegW<'_>, arg2: ParamRegW<'_>, @@ -166,14 +177,16 @@ pub(crate) unsafe fn syscall4( inout("$5") arg2.0 => _, in("$6") arg3.0, in("$7") arg4.0, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack), ); (RetReg(r1), RetReg(r2)) } } + +/// Raw semihosting call with 4 parameters that will be read (but not modified) by the host #[inline] -pub(crate) unsafe fn syscall4_readonly( +pub unsafe fn syscall4_readonly( op: OperationCode, arg1: ParamRegR<'_>, arg2: ParamRegR<'_>, @@ -191,7 +204,7 @@ pub(crate) unsafe fn syscall4_readonly( inout("$5") arg2.0 => _, in("$6") arg3.0, in("$7") arg4.0, - in("$25") op as usize, + in("$25") op.as_usize(), options(nostack, readonly), ); (RetReg(r1), RetReg(r2)) diff --git a/src/sys/mips/syscall/mod.rs b/src/sys/mips/syscall/mod.rs index c3e1493..56906da 100644 --- a/src/sys/mips/syscall/mod.rs +++ b/src/sys/mips/syscall/mod.rs @@ -2,13 +2,11 @@ //! Raw semihosting call. -// TODO: should we expose this as public API of `sys` module? - #![allow(clippy::needless_pass_by_value)] -pub(crate) use arch::{ - syscall0, syscall1_readonly, syscall2, syscall2_readonly, syscall3, syscall3_readonly, - syscall4, syscall4_readonly, +pub use arch::{ + syscall0, syscall1, syscall1_readonly, syscall2, syscall2_readonly, syscall3, + syscall3_readonly, syscall4, syscall4_readonly, }; #[cfg_attr( any( @@ -22,31 +20,63 @@ pub(crate) use arch::{ )] mod arch; -pub(crate) use crate::sys::reg::{ParamRegR, ParamRegW, RetReg}; +pub use crate::sys::reg::{ParamRegR, ParamRegW, RetReg}; /// Semihosting operation code. -#[derive(Clone, Copy)] -#[repr(usize)] +#[derive(Debug, Clone, Copy)] #[non_exhaustive] -pub(crate) enum OperationCode { - UHI_exit = 1, - UHI_open = 2, - UHI_close = 3, - UHI_read = 4, - UHI_write = 5, - UHI_lseek = 6, - UHI_unlink = 7, - UHI_fstat = 8, - UHI_argc = 9, - UHI_argnlen = 10, - UHI_argn = 11, +pub enum OperationCode { + UHI_exit, + UHI_open, + UHI_close, + UHI_read, + UHI_write, + UHI_lseek, + UHI_unlink, + UHI_fstat, + UHI_argc, + UHI_argnlen, + UHI_argn, // UHI_ramrange = 12, // QEMU (as of 7.2) doesn't support this // UHI_plog = 13, // TODO // UHI_assert = 14, // TODO // UHI_exception = 15, // QEMU (as of 7.2) doesn't support this - UHI_pread = 19, - UHI_pwrite = 20, - UHI_link = 22, + UHI_pread, + UHI_pwrite, + UHI_link, // UHI_boot_fail = 23, // QEMU (as of 7.2) doesn't support this + /// Some other (e.g. user defined) operation number + Other(usize), +} + +impl From for usize { + fn from(op: OperationCode) -> Self { + match op { + UHI_exit => 1, + UHI_open => 2, + UHI_close => 3, + UHI_read => 4, + UHI_write => 5, + UHI_lseek => 6, + UHI_unlink => 7, + UHI_fstat => 8, + UHI_argc => 9, + UHI_argnlen => 10, + UHI_argn => 11, + UHI_pread => 19, + UHI_pwrite => 20, + UHI_link => 22, + OperationCode::Other(op) => op, + } + } } + +impl OperationCode { + // Shortcut for >::into(op) + #[allow(dead_code)] + fn as_usize(self) -> usize { + self.into() + } +} + pub(crate) use OperationCode::*; diff --git a/src/sys/reg.rs b/src/sys/reg.rs index 8dbc2fe..a8e4a91 100644 --- a/src/sys/reg.rs +++ b/src/sys/reg.rs @@ -11,36 +11,38 @@ use crate::{ }; /// PARAMETER REGISTER (read-write) +#[allow(missing_debug_implementations)] +#[allow(clippy::exhaustive_structs)] #[repr(transparent)] -pub(crate) struct ParamRegW<'a>(pub(crate) *mut c_void, PhantomData<&'a mut ()>); +pub struct ParamRegW<'a>(pub *mut c_void, PhantomData<&'a mut ()>); impl<'a> ParamRegW<'a> { #[inline] - pub(crate) fn fd(fd: BorrowedFd<'a>) -> Self { + pub fn fd(fd: BorrowedFd<'a>) -> Self { Self::raw_fd(fd.as_raw_fd()) } #[inline] - pub(crate) fn raw_fd(fd: RawFd) -> Self { + pub fn raw_fd(fd: RawFd) -> Self { Self::isize(fd as isize) } #[inline] - pub(crate) fn usize(n: usize) -> Self { + pub fn usize(n: usize) -> Self { Self(n as *mut c_void, PhantomData) } #[allow(clippy::cast_sign_loss)] #[inline] - pub(crate) fn isize(n: isize) -> Self { + pub fn isize(n: isize) -> Self { Self::usize(n as usize) } #[inline] - pub(crate) fn ptr(ptr: *mut T) -> Self { + pub fn ptr(ptr: *mut T) -> Self { Self(ptr.cast::(), PhantomData) } #[inline] - pub(crate) fn ref_(r: &'a mut T) -> Self { + pub fn ref_(r: &'a mut T) -> Self { Self::ptr(r) } #[inline] - pub(crate) fn buf(buf: &'a mut [T]) -> Self { + pub fn buf(buf: &'a mut [T]) -> Self { Self::ptr(buf.as_mut_ptr()) } } @@ -52,42 +54,44 @@ impl<'a> ParamRegW<'a> { ))] impl<'a> ParamRegW<'a> { #[inline] - pub(crate) fn block(b: &'a mut [ParamRegW<'_>]) -> Self { + pub fn block(b: &'a mut [ParamRegW<'_>]) -> Self { Self::ptr(b.as_mut_ptr()) } } /// PARAMETER REGISTER (read-only) +#[allow(missing_debug_implementations)] +#[allow(clippy::exhaustive_structs)] #[repr(transparent)] -pub(crate) struct ParamRegR<'a>(pub(crate) *const c_void, PhantomData<&'a ()>); +pub struct ParamRegR<'a>(pub *const c_void, PhantomData<&'a ()>); impl<'a> ParamRegR<'a> { #[inline] - pub(crate) fn fd(fd: BorrowedFd<'a>) -> Self { + pub fn fd(fd: BorrowedFd<'a>) -> Self { Self::raw_fd(fd.as_raw_fd()) } #[inline] - pub(crate) fn raw_fd(fd: RawFd) -> Self { + pub fn raw_fd(fd: RawFd) -> Self { Self::isize(fd as isize) } #[inline] - pub(crate) fn usize(n: usize) -> Self { + pub fn usize(n: usize) -> Self { Self(n as *const c_void, PhantomData) } #[allow(clippy::cast_sign_loss)] #[inline] - pub(crate) fn isize(n: isize) -> Self { + pub fn isize(n: isize) -> Self { Self::usize(n as usize) } #[inline] - pub(crate) fn ptr(ptr: *const T) -> Self { + pub fn ptr(ptr: *const T) -> Self { Self(ptr.cast::(), PhantomData) } #[inline] - pub(crate) fn buf(buf: &'a [T]) -> Self { + pub fn buf(buf: &'a [T]) -> Self { Self::ptr(buf.as_ptr()) } #[inline] - pub(crate) fn c_str(s: &'a CStr) -> Self { + pub fn c_str(s: &'a CStr) -> Self { Self::ptr(s.as_ptr()) } } @@ -99,22 +103,24 @@ impl<'a> ParamRegR<'a> { ))] impl<'a> ParamRegR<'a> { #[inline] - pub(crate) fn block(b: &'a [ParamRegR<'_>]) -> Self { + pub fn block(b: &'a [ParamRegR<'_>]) -> Self { Self::ptr(b.as_ptr()) } #[inline] - pub(crate) fn ref_(r: &'a T) -> Self { + pub fn ref_(r: &'a T) -> Self { Self::ptr(r) } } /// RETURN REGISTER #[derive(Clone, Copy)] +#[allow(missing_debug_implementations)] +#[allow(clippy::exhaustive_structs)] #[repr(transparent)] -pub(crate) struct RetReg(pub(crate) *mut c_void); +pub struct RetReg(pub *mut c_void); impl RetReg { #[inline] - pub(crate) fn usize(self) -> usize { + pub fn usize(self) -> usize { self.0 as usize } #[allow(clippy::cast_possible_wrap, clippy::cast_sign_loss)] @@ -124,11 +130,11 @@ impl RetReg { } #[allow(clippy::cast_possible_truncation)] #[inline] - pub(crate) fn int(self) -> c_int { + pub fn int(self) -> c_int { self.isize() as c_int } #[inline] - pub(crate) fn raw_fd(self) -> Option { + pub fn raw_fd(self) -> Option { let fd = self.int(); if fd == -1 { None @@ -139,7 +145,7 @@ impl RetReg { } } #[inline] - pub(crate) fn errno(self) -> RawOsError { + pub fn errno(self) -> RawOsError { let err = self.int(); debug_assert!(!err.is_negative(), "{}", err); debug_assert_eq!(err as isize, self.isize()); @@ -155,7 +161,7 @@ impl RetReg { impl RetReg { #[allow(clippy::cast_possible_truncation)] #[inline] - pub(crate) fn u8(self) -> u8 { + pub fn u8(self) -> u8 { let b = self.usize() as u8; debug_assert_eq!(b as usize, self.usize()); b