diff --git a/rust/lib/mammoth/src/init.rs b/rust/lib/mammoth/src/init.rs new file mode 100644 index 0000000..a20aa76 --- /dev/null +++ b/rust/lib/mammoth/src/init.rs @@ -0,0 +1,42 @@ +use crate::syscall; +use crate::zion; +use crate::zion::z_cap_t; +use core::ffi::c_void; + +// From /zion/include/ztypes.h +const Z_INIT_SELF_PROC: u64 = 0x4000_0000; +const Z_INIT_SELF_VMAS: u64 = 0x4000_0001; +const Z_INIT_ENDPOINT: u64 = 0x4100_0000; + +pub static mut SELF_PROC_CAP: z_cap_t = 0; +pub static mut SELF_VMAS_CAP: z_cap_t = 0; +pub static mut INIT_ENDPOINT: z_cap_t = 0; + +pub fn parse_init_port(port_cap: z_cap_t) { + loop { + let mut num_bytes: u64 = 8; + let mut init_sig: u64 = 0; + let mut caps: [u64; 1] = [0]; + let mut num_caps: u64 = 1; + + let req = zion::ZPortPollReq { + port_cap, + num_bytes: &mut num_bytes as *mut u64, + data: &mut init_sig as *mut u64 as *mut c_void, + caps: &mut caps as *mut u64, + num_caps: &mut num_caps as *mut u64, + }; + let resp = syscall::syscall(zion::kZionPortPoll, &req); + if let Err(_) = resp { + break; + } + unsafe { + match init_sig { + Z_INIT_SELF_PROC => SELF_PROC_CAP = caps[0], + Z_INIT_SELF_VMAS => SELF_VMAS_CAP = caps[0], + Z_INIT_ENDPOINT => INIT_ENDPOINT = caps[0], + _ => syscall::debug("Unknown Cap in Init"), + } + } + } +} diff --git a/rust/lib/mammoth/src/lib.rs b/rust/lib/mammoth/src/lib.rs index 38564fd..3cc833d 100644 --- a/rust/lib/mammoth/src/lib.rs +++ b/rust/lib/mammoth/src/lib.rs @@ -5,67 +5,11 @@ extern crate alloc; -use core::ffi::c_void; - -pub mod mem; #[macro_use] +pub mod macros; + +pub mod init; +pub mod mem; pub mod syscall; pub mod thread; - -// From /zion/include/ztypes.h -const Z_INIT_SELF_PROC: u64 = 0x4000_0000; -const Z_INIT_SELF_VMAS: u64 = 0x4000_0001; -const Z_INIT_ENDPOINT: u64 = 0x4100_0000; - -static mut SELF_PROC_CAP: syscall::zcap = 0; -static mut SELF_VMAS_CAP: syscall::zcap = 0; -pub static mut INIT_ENDPOINT: syscall::zcap = 0; - -pub fn parse_init_port(port_cap: syscall::zcap) { - loop { - let mut num_bytes: u64 = 8; - let mut init_sig: u64 = 0; - let mut caps: [u64; 1] = [0]; - let mut num_caps: u64 = 1; - - let req = syscall::ZPortPollReq { - port_cap, - num_bytes: &mut num_bytes as *mut u64, - data: &mut init_sig as *mut u64 as *mut c_void, - caps: &mut caps as *mut u64, - num_caps: &mut num_caps as *mut u64, - }; - let resp = syscall::syscall(syscall::kZionPortPoll, &req); - if let Err(_) = resp { - break; - } - unsafe { - match init_sig { - Z_INIT_SELF_PROC => SELF_PROC_CAP = caps[0], - Z_INIT_SELF_VMAS => SELF_VMAS_CAP = caps[0], - Z_INIT_ENDPOINT => INIT_ENDPOINT = caps[0], - _ => syscall::debug("Unknown Cap in Init"), - } - } - } -} - -#[macro_export] -macro_rules! define_entry { - () => { - #[no_mangle] - pub extern "C" fn _start(init_port: mammoth::syscall::zcap) -> ! { - extern "C" { - fn main() -> z_err_t; - } - mammoth::parse_init_port(init_port); - mammoth::mem::init_heap(); - unsafe { - let err = main(); - let req = mammoth::syscall::ZProcessExitReq { code: err }; - let _ = mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req); - } - unreachable!() - } - }; -} +pub mod zion; diff --git a/rust/lib/mammoth/src/macros.rs b/rust/lib/mammoth/src/macros.rs new file mode 100644 index 0000000..8313961 --- /dev/null +++ b/rust/lib/mammoth/src/macros.rs @@ -0,0 +1,67 @@ +use alloc::string::String; +use alloc::vec::Vec; +use core::fmt; + +pub struct Writer { + int_vec: Vec, +} + +impl Writer { + pub fn new() -> Self { + Self { + int_vec: Vec::new(), + } + } +} + +impl Into for Writer { + fn into(self) -> String { + String::from_utf8(self.int_vec).expect("Failed to convert") + } +} + +impl fmt::Write for Writer { + fn write_str(&mut self, s: &str) -> fmt::Result { + for c in s.bytes() { + self.int_vec.push(c); + } + fmt::Result::Ok(()) + } +} + +#[macro_export] +macro_rules! debug { + () => { + $crate::syscall::debug(""); + }; + ($fmt:literal) => { + $crate::syscall::debug($fmt); + }; + ($fmt:literal, $($val:expr),+) => {{ + use core::fmt::Write as _; + let mut w = $crate::macros::Writer::new(); + write!(&mut w, $fmt, $($val),*).expect("Failed to format"); + let s: alloc::string::String = w.into(); + $crate::syscall::debug(&s); + }}; +} + +#[macro_export] +macro_rules! define_entry { + () => { + #[no_mangle] + pub extern "C" fn _start(init_port: mammoth::zion::z_cap_t) -> ! { + extern "C" { + fn main() -> z_err_t; + } + mammoth::init::parse_init_port(init_port); + mammoth::mem::init_heap(); + unsafe { + let err = main(); + let req = mammoth::zion::ZProcessExitReq { code: err }; + let _ = mammoth::syscall::syscall(mammoth::zion::kZionProcessExit, &req); + } + unreachable!() + } + }; +} diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 74bb1c4..dac6aa0 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -1,5 +1,6 @@ +use crate::init::SELF_VMAS_CAP; use crate::syscall; -use crate::SELF_VMAS_CAP; +use crate::zion; use linked_list_allocator::LockedHeap; #[global_allocator] @@ -11,16 +12,16 @@ pub fn init_heap() { // 1 MiB let size = 0x10_0000; let mut vmmo_cap = 0; - let obj_req = syscall::ZMemoryObjectCreateReq { + let obj_req = zion::ZMemoryObjectCreateReq { size, vmmo_cap: &mut vmmo_cap as *mut u64, }; - syscall::syscall(syscall::kZionMemoryObjectCreate, &obj_req) + syscall::syscall(zion::kZionMemoryObjectCreate, &obj_req) .expect("Failed to create memory object"); unsafe { let mut vaddr: u64 = 0; - let vmas_req = syscall::ZAddressSpaceMapReq { + let vmas_req = zion::ZAddressSpaceMapReq { vmmo_cap, vmas_cap: SELF_VMAS_CAP, align: 0x2000, @@ -28,7 +29,7 @@ pub fn init_heap() { vmas_offset: 0, }; - syscall::syscall(syscall::kZionAddressSpaceMap, &vmas_req) + syscall::syscall(zion::kZionAddressSpaceMap, &vmas_req) .expect("Failed to map memory object"); ALLOCATOR.lock().init(vaddr as *mut u8, size as usize); CAN_ALLOC = true; diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs index 8db78f6..d46bea0 100644 --- a/rust/lib/mammoth/src/syscall.rs +++ b/rust/lib/mammoth/src/syscall.rs @@ -1,85 +1,15 @@ extern crate alloc; -use alloc::string::String; -use alloc::vec::Vec; +use crate::zion; use core::ffi::c_void; -use core::fmt; use core::panic::PanicInfo; -include!("bindings.rs"); - -pub enum ZError { - UNKNOWN = 0x0, - // First set of error codes generally indicate user errors. - INVALID_ARGUMENT = 0x1, - NOT_FOUND = 0x2, - PERMISSION_DENIED = 0x3, - NULL_PTR = 0x4, - EMPTY = 0x5, - ALREADY_EXISTS = 0x6, - BUFFER_SIZE = 0x7, - FAILED_PRECONDITION = 0x8, - - // Second set of error codes generally indicate service errors. - INTERNAL = 0x100, - UNIMPLEMENTED = 0x101, - EXHAUSTED = 0x102, - INVALID_RESPONSE = 0x103, - - // Kernel specific error codes (relating to capabilities). - CAP_NOT_FOUND = 0x1000, - CAP_WRONG_TYPE = 0x1001, - CAP_PERMISSION_DENIED = 0x1002, -} - -impl From for ZError { - fn from(value: u64) -> Self { - match value { - 0x1 => ZError::INVALID_ARGUMENT, - 0x2 => ZError::NOT_FOUND, - 0x3 => ZError::PERMISSION_DENIED, - 0x4 => ZError::NULL_PTR, - 0x5 => ZError::EMPTY, - 0x6 => ZError::ALREADY_EXISTS, - 0x7 => ZError::BUFFER_SIZE, - 0x8 => ZError::FAILED_PRECONDITION, - - 0x100 => ZError::INTERNAL, - 0x101 => ZError::UNIMPLEMENTED, - 0x102 => ZError::EXHAUSTED, - 0x103 => ZError::INVALID_RESPONSE, - - 0x1000 => ZError::CAP_NOT_FOUND, - 0x1001 => ZError::CAP_WRONG_TYPE, - 0x1002 => ZError::CAP_PERMISSION_DENIED, - _ => ZError::UNKNOWN, - } - } -} - -impl fmt::Debug for ZError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let str = match self { - ZError::INVALID_ARGUMENT => "INVALID_ARGUMENT", - ZError::BUFFER_SIZE => "BUFFER_SIZE", - ZError::INTERNAL => "INTERNAL", - ZError::UNIMPLEMENTED => "UNIMPLEMENTED", - ZError::INVALID_RESPONSE => "INVALID_RESPONSE", - ZError::CAP_NOT_FOUND => "CAP_NOT_FOUND", - ZError::CAP_WRONG_TYPE => "CAP_WRONG_TYPE", - ZError::CAP_PERMISSION_DENIED => "CAP_PERMISSION_DENIED", - _ => "ZError", - }; - f.write_str(str) - } -} - #[must_use] -pub fn syscall(id: u64, req: &T) -> Result<(), ZError> { +pub fn syscall(id: u64, req: &T) -> Result<(), zion::ZError> { unsafe { - let resp = SysCall1(id, req as *const T as *const c_void); + let resp = zion::SysCall1(id, req as *const T as *const c_void); if resp != 0 { - return Err(ZError::from(resp)); + return Err(zion::ZError::from(resp)); } } Ok(()) @@ -95,60 +25,15 @@ fn panic(info: &PanicInfo) -> ! { } } // Internal error. - let req = ZProcessExitReq { code: 0x100 }; - let _ = syscall(kZionProcessExit, &req); + let req = zion::ZProcessExitReq { code: 0x100 }; + let _ = syscall(zion::kZionProcessExit, &req); unreachable!() } pub fn debug(msg: &str) { - let req = ZDebugReq { + let req = zion::ZDebugReq { message: msg.as_ptr() as *const i8, size: msg.len() as u64, }; - syscall(kZionDebug, &req).expect("Failed to write"); -} - -pub struct Writer { - int_vec: Vec, -} - -impl Writer { - pub fn new() -> Self { - Self { - int_vec: Vec::new(), - } - } -} - -impl Into for Writer { - fn into(self) -> String { - String::from_utf8(self.int_vec).expect("Failed to convert") - } -} - -impl fmt::Write for Writer { - fn write_str(&mut self, s: &str) -> fmt::Result { - for c in s.bytes() { - self.int_vec.push(c); - } - fmt::Result::Ok(()) - } -} - -#[macro_export] -macro_rules! debug { - () => { - $crate::syscall::debug(""); - }; - ($fmt:literal) => { - $crate::syscall::debug($fmt); - }; - ($fmt:literal, $($val:expr),+) => {{ - use core::fmt::Write as _; - use alloc::string::String; - let mut w = $crate::syscall::Writer::new(); - write!(&mut w, $fmt, $($val),*).expect("Failed to format"); - let s: String = w.into(); - $crate::syscall::debug(&s); - }}; + syscall(zion::kZionDebug, &req).expect("Failed to write"); } diff --git a/rust/lib/mammoth/src/thread.rs b/rust/lib/mammoth/src/thread.rs index 04c0366..d596c20 100644 --- a/rust/lib/mammoth/src/thread.rs +++ b/rust/lib/mammoth/src/thread.rs @@ -1,5 +1,6 @@ use crate::syscall; -use crate::syscall::z_cap_t; +use crate::zion; +use crate::zion::z_cap_t; use core::ffi::c_void; @@ -12,7 +13,7 @@ extern "C" fn entry_point(entry_ptr: *const ThreadEntry, arg1: *const c_void) -> entry(arg1); - let _ = syscall::syscall(syscall::kZionThreadExit, &syscall::ZThreadExitReq {}); + let _ = syscall::syscall(zion::kZionThreadExit, &zion::ZThreadExitReq {}); unreachable!(); } @@ -28,16 +29,16 @@ pub struct Thread<'a> { impl<'a> Thread<'a> { pub fn spawn(entry: &'a ThreadEntry, arg1: *const c_void) -> Self { let mut cap: z_cap_t = 0; - let req = syscall::ZThreadCreateReq { - proc_cap: unsafe { crate::SELF_PROC_CAP }, + let req = zion::ZThreadCreateReq { + proc_cap: unsafe { crate::init::SELF_PROC_CAP }, thread_cap: &mut cap as *mut z_cap_t, }; - syscall::syscall(syscall::kZionThreadCreate, &req).expect("Failed to create thread."); + syscall::syscall(zion::kZionThreadCreate, &req).expect("Failed to create thread."); syscall::syscall( - syscall::kZionThreadStart, - &syscall::ZThreadStartReq { + zion::kZionThreadStart, + &zion::ZThreadStartReq { thread_cap: cap, entry: entry_point as u64, arg1: entry as *const ThreadEntry as u64, @@ -49,10 +50,10 @@ impl<'a> Thread<'a> { Self { cap, _entry: entry } } - pub fn join(&self) -> Result<(), syscall::ZError> { + pub fn join(&self) -> Result<(), zion::ZError> { syscall::syscall( - syscall::kZionThreadWait, - &syscall::ZThreadWaitReq { + zion::kZionThreadWait, + &zion::ZThreadWaitReq { thread_cap: self.cap, }, ) diff --git a/rust/lib/mammoth/src/zion.rs b/rust/lib/mammoth/src/zion.rs new file mode 100644 index 0000000..1bcadd2 --- /dev/null +++ b/rust/lib/mammoth/src/zion.rs @@ -0,0 +1,69 @@ +include!("bindings.rs"); + +use core::fmt; + +pub enum ZError { + UNKNOWN = 0x0, + // First set of error codes generally indicate user errors. + INVALID_ARGUMENT = 0x1, + NOT_FOUND = 0x2, + PERMISSION_DENIED = 0x3, + NULL_PTR = 0x4, + EMPTY = 0x5, + ALREADY_EXISTS = 0x6, + BUFFER_SIZE = 0x7, + FAILED_PRECONDITION = 0x8, + + // Second set of error codes generally indicate service errors. + INTERNAL = 0x100, + UNIMPLEMENTED = 0x101, + EXHAUSTED = 0x102, + INVALID_RESPONSE = 0x103, + + // Kernel specific error codes (relating to capabilities). + CAP_NOT_FOUND = 0x1000, + CAP_WRONG_TYPE = 0x1001, + CAP_PERMISSION_DENIED = 0x1002, +} + +impl From for ZError { + fn from(value: u64) -> Self { + match value { + 0x1 => ZError::INVALID_ARGUMENT, + 0x2 => ZError::NOT_FOUND, + 0x3 => ZError::PERMISSION_DENIED, + 0x4 => ZError::NULL_PTR, + 0x5 => ZError::EMPTY, + 0x6 => ZError::ALREADY_EXISTS, + 0x7 => ZError::BUFFER_SIZE, + 0x8 => ZError::FAILED_PRECONDITION, + + 0x100 => ZError::INTERNAL, + 0x101 => ZError::UNIMPLEMENTED, + 0x102 => ZError::EXHAUSTED, + 0x103 => ZError::INVALID_RESPONSE, + + 0x1000 => ZError::CAP_NOT_FOUND, + 0x1001 => ZError::CAP_WRONG_TYPE, + 0x1002 => ZError::CAP_PERMISSION_DENIED, + _ => ZError::UNKNOWN, + } + } +} + +impl fmt::Debug for ZError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let str = match self { + ZError::INVALID_ARGUMENT => "INVALID_ARGUMENT", + ZError::BUFFER_SIZE => "BUFFER_SIZE", + ZError::INTERNAL => "INTERNAL", + ZError::UNIMPLEMENTED => "UNIMPLEMENTED", + ZError::INVALID_RESPONSE => "INVALID_RESPONSE", + ZError::CAP_NOT_FOUND => "CAP_NOT_FOUND", + ZError::CAP_WRONG_TYPE => "CAP_WRONG_TYPE", + ZError::CAP_PERMISSION_DENIED => "CAP_PERMISSION_DENIED", + _ => "ZError", + }; + f.write_str(str) + } +} diff --git a/rust/lib/yunq/src/buffer.rs b/rust/lib/yunq/src/buffer.rs index a070901..5c13c76 100644 --- a/rust/lib/yunq/src/buffer.rs +++ b/rust/lib/yunq/src/buffer.rs @@ -1,5 +1,5 @@ use alloc::boxed::Box; -use mammoth::syscall::ZError; +use mammoth::zion::ZError; pub struct ByteBuffer { buffer: Box<[u8; N]>, diff --git a/rust/lib/yunq/src/client.rs b/rust/lib/yunq/src/client.rs index 51795ed..dbe4657 100644 --- a/rust/lib/yunq/src/client.rs +++ b/rust/lib/yunq/src/client.rs @@ -2,8 +2,8 @@ use crate::buffer::ByteBuffer; use crate::message::YunqMessage; use alloc::vec::Vec; use core::ffi::c_void; -use mammoth::syscall::z_cap_t; -use mammoth::syscall::ZError; +use mammoth::zion::z_cap_t; +use mammoth::zion::ZError; const SENTINEL: u32 = 0xBEEFDEAD; @@ -22,7 +22,7 @@ pub fn call_endpoint( byte_buffer.write_at(4, (16 + length) as u32)?; let mut reply_port_cap: u64 = 0; - let send_req = mammoth::syscall::ZEndpointSendReq { + let send_req = mammoth::zion::ZEndpointSendReq { caps: cap_buffer.as_ptr(), num_caps: cap_buffer.len() as u64, endpoint_cap, @@ -31,13 +31,13 @@ pub fn call_endpoint( reply_port_cap: &mut reply_port_cap as *mut z_cap_t, }; - mammoth::syscall::syscall(mammoth::syscall::kZionEndpointSend, &send_req)?; + mammoth::syscall::syscall(mammoth::zion::kZionEndpointSend, &send_req)?; // FIXME: Add a way to zero out the byte buffer. let mut buffer_size = byte_buffer.size(); let mut num_caps: u64 = 10; cap_buffer = vec![0; num_caps as usize]; - let recv_req = mammoth::syscall::ZReplyPortRecvReq { + let recv_req = mammoth::zion::ZReplyPortRecvReq { reply_port_cap, caps: cap_buffer.as_mut_ptr(), num_caps: &mut num_caps as *mut u64, @@ -45,7 +45,7 @@ pub fn call_endpoint( num_bytes: &mut buffer_size as *mut u64, }; - mammoth::syscall::syscall(mammoth::syscall::kZionReplyPortRecv, &recv_req)?; + mammoth::syscall::syscall(mammoth::zion::kZionReplyPortRecv, &recv_req)?; if byte_buffer.at::(0)? != SENTINEL { return Err(ZError::INVALID_RESPONSE); diff --git a/rust/lib/yunq/src/message.rs b/rust/lib/yunq/src/message.rs index 357ec36..daab90f 100644 --- a/rust/lib/yunq/src/message.rs +++ b/rust/lib/yunq/src/message.rs @@ -1,7 +1,7 @@ use crate::buffer::ByteBuffer; use alloc::vec::Vec; -use mammoth::syscall::z_cap_t; -use mammoth::syscall::ZError; +use mammoth::zion::z_cap_t; +use mammoth::zion::ZError; pub const MESSAGE_IDENT: u32 = 0x33441122; pub const MESSAGE_HEADER_SIZE: usize = 24; // 4x uint32, 1x uint64 diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index 1b16921..b612523 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -8,8 +8,8 @@ use alloc::string::ToString; use mammoth::debug; use mammoth::define_entry; use mammoth::syscall::debug; -use mammoth::syscall::z_err_t; use mammoth::thread; +use mammoth::zion::z_err_t; use yellowstone::GetEndpointRequest; use yellowstone::YellowstoneClient; @@ -22,16 +22,16 @@ pub extern "C" fn main() -> z_err_t { debug(&x); debug!("Formatted {}", "string"); let mut vmmo_cap: u64 = 0; - let obj_req = mammoth::syscall::ZMemoryObjectCreateReq { + let obj_req = mammoth::zion::ZMemoryObjectCreateReq { size: 0, vmmo_cap: &mut vmmo_cap as *mut u64, }; - mammoth::syscall::syscall(mammoth::syscall::kZionMemoryObjectCreate, &obj_req) + mammoth::syscall::syscall(mammoth::zion::kZionMemoryObjectCreate, &obj_req) .expect("Failed to create memory object"); let mut yellowstone; unsafe { - yellowstone = YellowstoneClient::new(mammoth::INIT_ENDPOINT); + yellowstone = YellowstoneClient::new(mammoth::init::INIT_ENDPOINT); } let endpoint = yellowstone diff --git a/yunq/rust/src/codegen.rs b/yunq/rust/src/codegen.rs index 0051047..e20f6b5 100644 --- a/yunq/rust/src/codegen.rs +++ b/yunq/rust/src/codegen.rs @@ -79,8 +79,8 @@ pub fn generate_code(ast: &Vec) -> String { use alloc::string::String; use alloc::string::ToString; - use mammoth::syscall::z_cap_t; - use mammoth::syscall::ZError; + use mammoth::zion::z_cap_t; + use mammoth::zion::ZError; use yunq::ByteBuffer; use yunq::YunqMessage; use yunq_derive::YunqMessage;