Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions hermit-builtins/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions hermit-builtins/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,23 @@ edition = "2024"
[dependencies]
libm = "0.2"

#! ## MASOS dependencies
hermit-abi = { version = "0.5", optional = true }
spinning_top = { version = "0.3", optional = true }
talc = { version = "5", default-features = false, optional = true }

[lib]
crate-type = ["staticlib"]
harness = false

[features]
default = []
masos = [
"dep:hermit-abi",
"dep:spinning_top",
"dep:talc",
]

[profile.dist]
inherits = "release"
lto = "thin"
Expand Down
7 changes: 7 additions & 0 deletions hermit-builtins/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
#![no_std]
#![no_main]
#![feature(linkage)]
#![cfg_attr(feature = "masos", feature(macro_metavar_expr_concat))]
#![cfg_attr(feature = "masos", feature(thread_local))]

#[cfg(feature = "masos")]
extern crate alloc;

#[cfg(feature = "masos")]
mod masos;
pub mod math;

#[panic_handler]
Expand Down
65 changes: 65 additions & 0 deletions hermit-builtins/src/masos/alloc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use alloc::alloc::{alloc, alloc_zeroed, dealloc, realloc};
use core::alloc::Layout;
use core::mem::MaybeUninit;

use spinning_top::RawSpinlock;
use talc::TalcLock;
use talc::source::Claim;

#[global_allocator]
static TALC: TalcLock<RawSpinlock, Claim> = TalcLock::new(unsafe {
/// 16 MiB of statically allocated Heap memory.
#[repr(C, align(0x1000))]
struct Heap([MaybeUninit<u8>; 0x100_0000]);

static mut HEAP: Heap = Heap([MaybeUninit::uninit(); _]);

let base = (&raw mut HEAP).cast::<u8>();
let size = size_of::<Heap>();
Claim::new(base, size)
});

#[unsafe(no_mangle)]
unsafe extern "C" fn sys_alloc(size: usize, align: usize) -> *mut u8 {
unsafe { alloc(layout_from_size_align(size, align)) }
}

#[unsafe(no_mangle)]
unsafe extern "C" fn sys_dealloc(ptr: *mut u8, size: usize, align: usize) {
unsafe { dealloc(ptr, layout_from_size_align(size, align)) }
}

#[unsafe(no_mangle)]
unsafe extern "C" fn sys_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
unsafe { alloc_zeroed(layout_from_size_align(size, align)) }
}

#[unsafe(no_mangle)]
unsafe extern "C" fn sys_realloc(
ptr: *mut u8,
size: usize,
align: usize,
new_size: usize,
) -> *mut u8 {
unsafe { realloc(ptr, layout_from_size_align(size, align), new_size) }
}

/// Deprecated
#[unsafe(no_mangle)]
unsafe extern "C" fn sys_malloc(size: usize, align: usize) -> *mut u8 {
unsafe { sys_alloc(size, align) }
}

/// Deprecated
#[unsafe(no_mangle)]
unsafe extern "C" fn sys_free(ptr: *mut u8, size: usize, align: usize) {
unsafe { sys_dealloc(ptr, size, align) }
}

unsafe fn layout_from_size_align(size: usize, align: usize) -> Layout {
if cfg!(debug_assertions) {
Layout::from_size_align(size, align).unwrap()
} else {
unsafe { Layout::from_size_align_unchecked(size, align) }
}
}
122 changes: 122 additions & 0 deletions hermit-builtins/src/masos/arch/aarch64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use core::arch::asm;

#[inline]
pub(crate) unsafe fn syscall0(nr: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
lateout("x0") r0,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall1(nr: usize, a0: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall2(nr: usize, a0: usize, a1: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
in("x1") a1,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall3(nr: usize, a0: usize, a1: usize, a2: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
in("x1") a1,
in("x2") a2,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall4(nr: usize, a0: usize, a1: usize, a2: usize, a3: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
in("x1") a1,
in("x2") a2,
in("x3") a3,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall5(nr: usize, a0: usize, a1: usize, a2: usize, a3: usize, a4: usize) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
in("x1") a1,
in("x2") a2,
in("x3") a3,
in("x4") a4,
options(preserves_flags),
);
}
r0
}

#[inline]
pub(crate) unsafe fn syscall6(
nr: usize,
a0: usize,
a1: usize,
a2: usize,
a3: usize,
a4: usize,
a5: usize,
) -> usize {
let r0;
unsafe {
asm!(
"svc 0",
in("x8") nr,
inlateout("x0") a0 => r0,
in("x1") a1,
in("x2") a2,
in("x3") a3,
in("x4") a4,
in("x5") a5,
options(preserves_flags),
);
}
r0
}
62 changes: 62 additions & 0 deletions hermit-builtins/src/masos/arch/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
cfg_select! {
target_arch = "aarch64" => {
mod aarch64;
pub(crate) use aarch64::*;
}
target_arch = "x86_64" => {
mod x86_64;
pub(crate) use x86_64::*;
}
_ => {}
}

macro_rules! syscall {
($nr:expr $(,)?) => {
$crate::masos::arch::syscall0($nr as usize)
};

($nr:expr, $a0:expr $(,)?) => {
$crate::masos::arch::syscall1($nr as usize, $a0 as usize)
};

($nr:expr, $a0:expr, $a1:expr $(,)?) => {
$crate::masos::arch::syscall2($nr as usize, $a0 as usize, $a1 as usize)
};

($nr:expr, $a0:expr, $a1:expr, $a2:expr $(,)?) => {
$crate::masos::arch::syscall3($nr as usize, $a0 as usize, $a1 as usize, $a2 as usize)
};

($nr:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr $(,)?) => {
$crate::masos::arch::syscall4(
$nr as usize,
$a0 as usize,
$a1 as usize,
$a2 as usize,
$a3 as usize,
)
};

($nr:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr $(,)?) => {
$crate::masos::arch::syscall5(
$nr as usize,
$a0 as usize,
$a1 as usize,
$a2 as usize,
$a3 as usize,
$a4 as usize,
)
};

($nr:expr, $a0:expr, $a1:expr, $a2:expr, $a3:expr, $a4:expr, $a5:expr $(,)?) => {
$crate::masos::arch::syscall6(
$nr as usize,
$a0 as usize,
$a1 as usize,
$a2 as usize,
$a3 as usize,
$a4 as usize,
$a5 as usize,
)
};
}
Loading
Loading