syscall.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. use super::task::ThreadAlloc;
  2. use crate::kernel::task::Thread;
  3. use alloc::boxed::Box;
  4. use core::{future::Future, marker::PhantomData, ops::Deref, pin::Pin};
  5. use eonix_mm::address::{Addr, VAddr};
  6. use eonix_sync::LazyLock;
  7. use posix_types::ctypes::PtrT;
  8. pub mod file_rw;
  9. pub mod mm;
  10. pub mod net;
  11. pub mod procops;
  12. pub mod sysinfo;
  13. const MAX_SYSCALL_NO: usize = 512;
  14. #[derive(Debug, Clone, Copy)]
  15. pub struct SyscallNoReturn;
  16. #[derive(Clone, Copy)]
  17. pub struct User<T>(VAddr, PhantomData<T>);
  18. #[derive(Clone, Copy)]
  19. pub struct UserMut<T>(VAddr, PhantomData<T>);
  20. #[repr(C)]
  21. pub(self) struct RawSyscallHandler {
  22. no: usize,
  23. handler: for<'thd, 'alloc> fn(
  24. &'thd Thread,
  25. ThreadAlloc<'alloc>,
  26. [usize; 6],
  27. ) -> Pin<
  28. Box<dyn Future<Output = Option<usize>> + Send + 'thd, ThreadAlloc<'alloc>>,
  29. >,
  30. name: &'static str,
  31. }
  32. pub struct SyscallHandler {
  33. pub handler: for<'thd, 'alloc> fn(
  34. &'thd Thread,
  35. ThreadAlloc<'alloc>,
  36. [usize; 6],
  37. ) -> Pin<
  38. Box<dyn Future<Output = Option<usize>> + Send + 'thd, ThreadAlloc<'alloc>>,
  39. >,
  40. pub name: &'static str,
  41. }
  42. pub trait FromSyscallArg: core::fmt::Debug {
  43. fn from_arg(value: usize) -> Self;
  44. }
  45. pub trait SyscallRetVal: core::fmt::Debug {
  46. fn into_retval(self) -> Option<usize>;
  47. }
  48. impl<T> SyscallRetVal for Result<T, u32>
  49. where
  50. T: SyscallRetVal,
  51. {
  52. fn into_retval(self) -> Option<usize> {
  53. match self {
  54. Ok(v) => v.into_retval(),
  55. Err(e) => Some((-(e as isize)) as usize),
  56. }
  57. }
  58. }
  59. impl SyscallRetVal for () {
  60. fn into_retval(self) -> Option<usize> {
  61. Some(0)
  62. }
  63. }
  64. impl SyscallRetVal for u32 {
  65. fn into_retval(self) -> Option<usize> {
  66. Some(self as usize)
  67. }
  68. }
  69. impl SyscallRetVal for usize {
  70. fn into_retval(self) -> Option<usize> {
  71. Some(self)
  72. }
  73. }
  74. impl SyscallRetVal for isize {
  75. fn into_retval(self) -> Option<usize> {
  76. Some(self as usize)
  77. }
  78. }
  79. impl SyscallRetVal for i32 {
  80. fn into_retval(self) -> Option<usize> {
  81. Some(self as usize)
  82. }
  83. }
  84. impl SyscallRetVal for SyscallNoReturn {
  85. fn into_retval(self) -> Option<usize> {
  86. None
  87. }
  88. }
  89. impl<T> SyscallRetVal for User<T> {
  90. fn into_retval(self) -> Option<usize> {
  91. Some(self.0.addr())
  92. }
  93. }
  94. impl<T> SyscallRetVal for UserMut<T> {
  95. fn into_retval(self) -> Option<usize> {
  96. Some(self.0.addr())
  97. }
  98. }
  99. #[cfg(not(target_arch = "x86_64"))]
  100. impl SyscallRetVal for u64 {
  101. fn into_retval(self) -> Option<usize> {
  102. Some(self as usize)
  103. }
  104. }
  105. #[cfg(not(target_arch = "x86_64"))]
  106. impl FromSyscallArg for u64 {
  107. fn from_arg(value: usize) -> u64 {
  108. value as u64
  109. }
  110. }
  111. impl FromSyscallArg for u32 {
  112. fn from_arg(value: usize) -> u32 {
  113. value as u32
  114. }
  115. }
  116. impl FromSyscallArg for i32 {
  117. fn from_arg(value: usize) -> i32 {
  118. value as i32
  119. }
  120. }
  121. impl FromSyscallArg for usize {
  122. fn from_arg(value: usize) -> usize {
  123. value
  124. }
  125. }
  126. impl FromSyscallArg for PtrT {
  127. fn from_arg(value: usize) -> Self {
  128. PtrT::new(value).expect("Invalid user pointer value")
  129. }
  130. }
  131. impl<T> FromSyscallArg for User<T> {
  132. fn from_arg(value: usize) -> User<T> {
  133. User(VAddr::from(value), PhantomData)
  134. }
  135. }
  136. impl<T> FromSyscallArg for UserMut<T> {
  137. fn from_arg(value: usize) -> UserMut<T> {
  138. UserMut(VAddr::from(value), PhantomData)
  139. }
  140. }
  141. impl<T> User<T> {
  142. pub const fn new(addr: VAddr) -> Self {
  143. Self(addr, PhantomData)
  144. }
  145. pub const fn with_addr(addr: usize) -> Self {
  146. Self::new(VAddr::from(addr))
  147. }
  148. pub const fn null() -> Self {
  149. Self(VAddr::NULL, PhantomData)
  150. }
  151. pub fn is_null(&self) -> bool {
  152. self.0.addr() == 0
  153. }
  154. pub const fn cast<U>(self) -> User<U> {
  155. User(self.0, PhantomData)
  156. }
  157. pub fn offset(self, off: isize) -> Self {
  158. Self(
  159. VAddr::from(
  160. self.0
  161. .addr()
  162. .checked_add_signed(off)
  163. .expect("offset overflow"),
  164. ),
  165. PhantomData,
  166. )
  167. }
  168. pub const unsafe fn as_mut(self) -> UserMut<T> {
  169. UserMut(self.0, PhantomData)
  170. }
  171. }
  172. impl<T> UserMut<T> {
  173. pub const fn new(addr: VAddr) -> Self {
  174. Self(addr, PhantomData)
  175. }
  176. pub const fn with_addr(addr: usize) -> Self {
  177. Self::new(VAddr::from(addr))
  178. }
  179. pub const fn null() -> Self {
  180. Self(VAddr::NULL, PhantomData)
  181. }
  182. pub fn is_null(&self) -> bool {
  183. self.0.addr() == 0
  184. }
  185. pub const fn cast<U>(self) -> UserMut<U> {
  186. UserMut(self.0, PhantomData)
  187. }
  188. pub fn offset(self, off: isize) -> Self {
  189. Self(
  190. VAddr::from(
  191. self.0
  192. .addr()
  193. .checked_add_signed(off)
  194. .expect("offset overflow"),
  195. ),
  196. PhantomData,
  197. )
  198. }
  199. pub const fn as_const(self) -> User<T> {
  200. User(self.0, PhantomData)
  201. }
  202. pub const fn vaddr(&self) -> VAddr {
  203. self.0
  204. }
  205. }
  206. impl<T> Deref for User<T> {
  207. type Target = VAddr;
  208. fn deref(&self) -> &Self::Target {
  209. &self.0
  210. }
  211. }
  212. impl<T> Deref for UserMut<T> {
  213. type Target = VAddr;
  214. fn deref(&self) -> &Self::Target {
  215. &self.0
  216. }
  217. }
  218. impl<T> core::fmt::Debug for User<T> {
  219. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  220. match self.0 {
  221. VAddr::NULL => write!(f, "User(NULL)"),
  222. _ => write!(f, "User({:#018x?})", self.0.addr()),
  223. }
  224. }
  225. }
  226. impl<T> core::fmt::Debug for UserMut<T> {
  227. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  228. match self.0 {
  229. VAddr::NULL => write!(f, "UserMut(NULL)"),
  230. _ => write!(f, "UserMut({:#018x?})", self.0.addr()),
  231. }
  232. }
  233. }
  234. static SYSCALL_HANDLERS: LazyLock<[Option<SyscallHandler>; MAX_SYSCALL_NO]> = LazyLock::new(|| {
  235. extern "C" {
  236. // SAFETY: `SYSCALL_HANDLERS` is defined in linker script.
  237. fn RAW_SYSCALL_HANDLERS();
  238. fn RAW_SYSCALL_HANDLERS_SIZE();
  239. }
  240. // DO NOT TOUCH THESE FUNCTIONS!!!
  241. // THEY ARE USED FOR KEEPING THE OBJECTS NOT STRIPPED BY THE LINKER!!!
  242. file_rw::keep_alive();
  243. mm::keep_alive();
  244. net::keep_alive();
  245. procops::keep_alive();
  246. sysinfo::keep_alive();
  247. let raw_handlers_addr = RAW_SYSCALL_HANDLERS as *const ();
  248. let raw_handlers_size_byte = RAW_SYSCALL_HANDLERS_SIZE as usize;
  249. assert!(raw_handlers_size_byte % size_of::<RawSyscallHandler>() == 0);
  250. let raw_handlers_count = raw_handlers_size_byte / size_of::<RawSyscallHandler>();
  251. let raw_handlers = unsafe {
  252. core::slice::from_raw_parts(
  253. raw_handlers_addr as *const RawSyscallHandler,
  254. raw_handlers_count,
  255. )
  256. };
  257. let mut handlers = [const { None }; MAX_SYSCALL_NO];
  258. for &RawSyscallHandler { no, handler, name } in raw_handlers.iter() {
  259. handlers[no] = Some(SyscallHandler { handler, name })
  260. }
  261. handlers
  262. });
  263. pub fn syscall_handlers() -> &'static [Option<SyscallHandler>] {
  264. SYSCALL_HANDLERS.as_ref()
  265. }