From 32ccbedb7a686038b35e8876c7dedadb26dd2c7d Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Fri, 26 Jul 2024 15:20:21 -0700 Subject: [PATCH] Basic allocations in rust user-space. --- rust/.cargo/config.toml | 2 +- rust/Cargo.lock | 43 +++++++++++++++++++++++++++++++ rust/lib/mammoth/Cargo.toml | 1 + rust/lib/mammoth/src/lib.rs | 45 ++++++++++----------------------- rust/lib/mammoth/src/mem.rs | 31 +++++++++++++++++++++++ rust/lib/mammoth/src/syscall.rs | 31 +++++++++++++++++++++++ rust/usr/testbed/src/main.rs | 9 +++++-- 7 files changed, 127 insertions(+), 35 deletions(-) create mode 100644 rust/lib/mammoth/src/mem.rs create mode 100644 rust/lib/mammoth/src/syscall.rs diff --git a/rust/.cargo/config.toml b/rust/.cargo/config.toml index b935b9b..220a396 100644 --- a/rust/.cargo/config.toml +++ b/rust/.cargo/config.toml @@ -1,6 +1,6 @@ [unstable] build-std-features = ["compiler-builtins-mem"] -build-std = ["core", "compiler_builtins"] +build-std = ["core", "compiler_builtins", "alloc"] [build] target = "x86_64-acadia-os.json" diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 9ccd58d..f0b3f19 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -2,9 +2,52 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "linked_list_allocator" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" +dependencies = [ + "spinning_top", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + [[package]] name = "mammoth" version = "0.1.0" +dependencies = [ + "linked_list_allocator", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "spinning_top" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9eb1a2f4c41445a3a0ff9abc5221c5fcd28e1f13cd7c0397706f9ac938ddb0" +dependencies = [ + "lock_api", +] [[package]] name = "testbed" diff --git a/rust/lib/mammoth/Cargo.toml b/rust/lib/mammoth/Cargo.toml index 4577b56..f14c35d 100644 --- a/rust/lib/mammoth/Cargo.toml +++ b/rust/lib/mammoth/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" name = "mammoth" [dependencies] +linked_list_allocator = "0.10.5" [build-dependencies] diff --git a/rust/lib/mammoth/src/lib.rs b/rust/lib/mammoth/src/lib.rs index 863d06d..7878923 100644 --- a/rust/lib/mammoth/src/lib.rs +++ b/rust/lib/mammoth/src/lib.rs @@ -4,54 +4,34 @@ #![allow(non_snake_case)] use core::ffi::c_void; -use core::panic::PanicInfo; -include!("bindings.rs"); - -pub fn syscall(id: u64, req: &T) -> u64 { - unsafe { SysCall1(id, req as *const T as *const c_void) } -} - -#[panic_handler] -fn panic(_info: &PanicInfo) -> ! { - // Internal error. - let req = ZProcessExitReq { code: 0x100 }; - syscall(kZionProcessExit, &req); - unreachable!() -} - -pub fn debug(msg: &str) { - let req = ZDebugReq { - message: msg.as_ptr() as *const i8, - size: msg.len() as u64, - }; - syscall(kZionDebug, &req); -} +pub mod mem; +pub mod syscall; // 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: zcap = 0; -static mut SELF_VMAS_CAP: zcap = 0; -static mut INIT_ENDPOINT: zcap = 0; +static mut SELF_PROC_CAP: syscall::zcap = 0; +static mut SELF_VMAS_CAP: syscall::zcap = 0; +static mut INIT_ENDPOINT: syscall::zcap = 0; -pub fn parse_init_port(port_cap: zcap) { +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 = ZPortPollReq { + 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(kZionPortPoll, &req); + let resp = syscall::syscall(syscall::kZionPortPoll, &req); if resp != 0 { break; } @@ -60,7 +40,7 @@ pub fn parse_init_port(port_cap: zcap) { 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], - _ => debug("Unknown Cap in Init"), + _ => syscall::debug("Unknown Cap in Init"), } } } @@ -70,15 +50,16 @@ pub fn parse_init_port(port_cap: zcap) { macro_rules! define_entry { () => { #[no_mangle] - pub extern "C" fn _start(init_port: mammoth::zcap) -> ! { + 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::ZProcessExitReq { code: err }; - mammoth::syscall(mammoth::kZionProcessExit, &req); + let req = mammoth::syscall::ZProcessExitReq { code: err }; + mammoth::syscall::syscall(mammoth::syscall::kZionProcessExit, &req); } unreachable!() } diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs new file mode 100644 index 0000000..12b3832 --- /dev/null +++ b/rust/lib/mammoth/src/mem.rs @@ -0,0 +1,31 @@ +use crate::syscall; +use crate::SELF_VMAS_CAP; +use linked_list_allocator::LockedHeap; + +#[global_allocator] +static ALLOCATOR: LockedHeap = LockedHeap::empty(); + +pub fn init_heap() { + // 1 MiB + let size = 0x10_0000; + let mut vmmo_cap = 0; + let obj_req = syscall::ZMemoryObjectCreateReq { + size, + vmmo_cap: &mut vmmo_cap as *mut u64, + }; + syscall::checked_syscall(syscall::kZionMemoryObjectCreate, &obj_req); + + unsafe { + let mut vaddr: u64 = 0; + let vmas_req = syscall::ZAddressSpaceMapReq { + vmmo_cap, + vmas_cap: SELF_VMAS_CAP, + align: 0x2000, + vaddr: &mut vaddr as *mut u64, + vmas_offset: 0, + }; + + syscall::checked_syscall(syscall::kZionAddressSpaceMap, &vmas_req); + ALLOCATOR.lock().init(vaddr as *mut u8, size as usize); + } +} diff --git a/rust/lib/mammoth/src/syscall.rs b/rust/lib/mammoth/src/syscall.rs new file mode 100644 index 0000000..030edc1 --- /dev/null +++ b/rust/lib/mammoth/src/syscall.rs @@ -0,0 +1,31 @@ +use core::ffi::c_void; +use core::panic::PanicInfo; + +include!("bindings.rs"); + +pub fn syscall(id: u64, req: &T) -> u64 { + unsafe { SysCall1(id, req as *const T as *const c_void) } +} + +pub fn checked_syscall(id: u64, req: &T) { + if syscall(id, req) != 0 { + debug("Bad syscall response."); + panic!(); + } +} + +#[panic_handler] +fn panic(_info: &PanicInfo) -> ! { + // Internal error. + let req = ZProcessExitReq { code: 0x100 }; + syscall(kZionProcessExit, &req); + unreachable!() +} + +pub fn debug(msg: &str) { + let req = ZDebugReq { + message: msg.as_ptr() as *const i8, + size: msg.len() as u64, + }; + syscall(kZionDebug, &req); +} diff --git a/rust/usr/testbed/src/main.rs b/rust/usr/testbed/src/main.rs index 53a54fe..3804002 100644 --- a/rust/usr/testbed/src/main.rs +++ b/rust/usr/testbed/src/main.rs @@ -1,14 +1,19 @@ #![no_std] #![no_main] -use mammoth::debug; +extern crate alloc; + +use alloc::boxed::Box; use mammoth::define_entry; -use mammoth::z_err_t; +use mammoth::syscall::debug; +use mammoth::syscall::z_err_t; define_entry!(); #[no_mangle] pub extern "C" fn main() -> z_err_t { debug("Testing!"); + let x = Box::new("Heap str"); + debug(&x); 0 }