refactor: remove old userspace and userspace-rt crates
This commit is contained in:
15
Cargo.lock
generated
15
Cargo.lock
generated
@@ -337,18 +337,3 @@ version = "0.1.0"
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "user-manager"
|
name = "user-manager"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "userspace"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"types",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "userspace-rt"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"types",
|
|
||||||
"userspace",
|
|
||||||
]
|
|
||||||
|
|||||||
@@ -39,8 +39,6 @@ members = [
|
|||||||
"crates/servers/usb-server",
|
"crates/servers/usb-server",
|
||||||
"crates/servers/user-manager",
|
"crates/servers/user-manager",
|
||||||
"crates/types",
|
"crates/types",
|
||||||
"crates/userspace",
|
|
||||||
"crates/userspace-rt",
|
|
||||||
"crates/ports/framebuffer",
|
"crates/ports/framebuffer",
|
||||||
"crates/ports/block-device",
|
"crates/ports/block-device",
|
||||||
"crates/ports/input-device",
|
"crates/ports/input-device",
|
||||||
@@ -66,8 +64,6 @@ elf = { path = "crates/elf" }
|
|||||||
platform = { path = "crates/platform" }
|
platform = { path = "crates/platform" }
|
||||||
kernel = { path = "crates/kernel" }
|
kernel = { path = "crates/kernel" }
|
||||||
server-framework = { path = "crates/server-framework" }
|
server-framework = { path = "crates/server-framework" }
|
||||||
userspace = { path = "crates/userspace" }
|
|
||||||
userspace-rt = { path = "crates/userspace-rt" }
|
|
||||||
|
|
||||||
# servers
|
# servers
|
||||||
accessibility-server = { path = "crates/servers/accessibility-server" }
|
accessibility-server = { path = "crates/servers/accessibility-server" }
|
||||||
|
|||||||
@@ -1,8 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "userspace-rt"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
types = { workspace = true }
|
|
||||||
userspace = { workspace = true }
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
fn main() {
|
|
||||||
let ld = std::path::Path::new("linker.ld").canonicalize().unwrap();
|
|
||||||
println!("cargo:rustc-link-arg=-T{}", ld.display());
|
|
||||||
println!("cargo:rerun-if-changed=linker.ld");
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
OUTPUT_ARCH(riscv)
|
|
||||||
ENTRY(_start)
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
. = 0x10000;
|
|
||||||
|
|
||||||
.text : {
|
|
||||||
*(.text.entry)
|
|
||||||
*(.text .text.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
. = ALIGN(4096);
|
|
||||||
.rodata : { *(.rodata .rodata.*) }
|
|
||||||
|
|
||||||
. = ALIGN(4096);
|
|
||||||
.data : { *(.data .data.*) }
|
|
||||||
|
|
||||||
. = ALIGN(4096);
|
|
||||||
.bss : {
|
|
||||||
*(.bss .bss.*)
|
|
||||||
*(.sbss .sbss.*)
|
|
||||||
}
|
|
||||||
|
|
||||||
/DISCARD/ : { *(.eh_frame) }
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#[cfg(all(target_arch = "riscv64", target_os = "none"))]
|
|
||||||
mod riscv;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
use core::arch::global_asm;
|
|
||||||
|
|
||||||
global_asm!(
|
|
||||||
r#"
|
|
||||||
.section .text.entry
|
|
||||||
.globl _start
|
|
||||||
_start:
|
|
||||||
call main
|
|
||||||
li a7, 16
|
|
||||||
ecall
|
|
||||||
j _start
|
|
||||||
"#
|
|
||||||
);
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
|
|
||||||
mod arch;
|
|
||||||
|
|
||||||
pub use userspace::syscall;
|
|
||||||
pub use userspace::allocator::KosAllocator;
|
|
||||||
|
|
||||||
#[cfg(target_os = "none")]
|
|
||||||
#[panic_handler]
|
|
||||||
fn panic(_: &core::panic::PanicInfo) -> ! {
|
|
||||||
userspace::syscall::exit();
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "userspace"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2024"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
types = { workspace = true }
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use core::alloc::{GlobalAlloc, Layout};
|
|
||||||
use core::cell::UnsafeCell;
|
|
||||||
use core::ptr;
|
|
||||||
|
|
||||||
const PAGE_SIZE: usize = 4096;
|
|
||||||
const MAX_PAGES: usize = 64;
|
|
||||||
|
|
||||||
struct FreeBlock {
|
|
||||||
size: usize,
|
|
||||||
next: *mut FreeBlock,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct KosAllocator {
|
|
||||||
inner: UnsafeCell<AllocatorInner>,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct AllocatorInner {
|
|
||||||
free_list: *mut FreeBlock,
|
|
||||||
pages: [usize; MAX_PAGES],
|
|
||||||
page_count: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for KosAllocator {}
|
|
||||||
|
|
||||||
impl KosAllocator {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: UnsafeCell::new(AllocatorInner {
|
|
||||||
free_list: ptr::null_mut(),
|
|
||||||
pages: [0; MAX_PAGES],
|
|
||||||
page_count: 0,
|
|
||||||
}),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn inner_mut(&self) -> &mut AllocatorInner {
|
|
||||||
unsafe { &mut *self.inner.get() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AllocatorInner {
|
|
||||||
fn request_page(&mut self) -> *mut u8 {
|
|
||||||
if self.page_count >= MAX_PAGES {
|
|
||||||
return ptr::null_mut();
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = match types::bounded::PageCount::new(1) {
|
|
||||||
Some(c) => c,
|
|
||||||
None => return ptr::null_mut(),
|
|
||||||
};
|
|
||||||
let va = match crate::syscall::request_pages(count) {
|
|
||||||
Some(va) => va,
|
|
||||||
None => return ptr::null_mut(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.pages[self.page_count] = va.raw();
|
|
||||||
self.page_count += 1;
|
|
||||||
va.raw() as *mut u8
|
|
||||||
}
|
|
||||||
|
|
||||||
fn alloc_from_free_list(&mut self, size: usize, align: usize) -> *mut u8 {
|
|
||||||
let mut prev: *mut FreeBlock = ptr::null_mut();
|
|
||||||
let mut current = self.free_list;
|
|
||||||
|
|
||||||
while !current.is_null() {
|
|
||||||
let block = unsafe { &mut *current };
|
|
||||||
let addr = current as usize;
|
|
||||||
let aligned = (addr + align - 1) & !(align - 1);
|
|
||||||
let padding = aligned - addr;
|
|
||||||
|
|
||||||
if block.size >= size + padding {
|
|
||||||
let remaining = block.size - size - padding;
|
|
||||||
|
|
||||||
if remaining >= core::mem::size_of::<FreeBlock>() {
|
|
||||||
let new_block = (aligned + size) as *mut FreeBlock;
|
|
||||||
unsafe {
|
|
||||||
(*new_block).size = remaining;
|
|
||||||
(*new_block).next = block.next;
|
|
||||||
}
|
|
||||||
if prev.is_null() {
|
|
||||||
self.free_list = new_block;
|
|
||||||
} else {
|
|
||||||
unsafe { (*prev).next = new_block; }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if prev.is_null() {
|
|
||||||
self.free_list = block.next;
|
|
||||||
} else {
|
|
||||||
unsafe { (*prev).next = block.next; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return aligned as *mut u8;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = current;
|
|
||||||
current = block.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_to_free_list(&mut self, ptr: *mut u8, size: usize) {
|
|
||||||
let block = ptr as *mut FreeBlock;
|
|
||||||
unsafe {
|
|
||||||
(*block).size = size;
|
|
||||||
(*block).next = self.free_list;
|
|
||||||
}
|
|
||||||
self.free_list = block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl GlobalAlloc for KosAllocator {
|
|
||||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
|
||||||
let inner = self.inner_mut();
|
|
||||||
let size = layout.size().max(core::mem::size_of::<FreeBlock>());
|
|
||||||
let align = layout.align();
|
|
||||||
|
|
||||||
let ptr = inner.alloc_from_free_list(size, align);
|
|
||||||
if !ptr.is_null() {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
let pages_needed = (size + PAGE_SIZE - 1) / PAGE_SIZE;
|
|
||||||
for _ in 0..pages_needed {
|
|
||||||
let page = inner.request_page();
|
|
||||||
if page.is_null() {
|
|
||||||
return ptr::null_mut();
|
|
||||||
}
|
|
||||||
inner.add_to_free_list(page, PAGE_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.alloc_from_free_list(size, align)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
|
||||||
let inner = self.inner_mut();
|
|
||||||
let size = layout.size().max(core::mem::size_of::<FreeBlock>());
|
|
||||||
inner.add_to_free_list(ptr, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,81 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
use core::alloc::Layout;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn allocator_creates_successfully() {
|
|
||||||
let _alloc = KosAllocator::new();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn free_list_operations() {
|
|
||||||
let alloc = KosAllocator::new();
|
|
||||||
let inner = alloc.inner_mut();
|
|
||||||
|
|
||||||
// Simulate a page by using a stack buffer
|
|
||||||
let mut page = [0u8; 4096];
|
|
||||||
let page_ptr = page.as_mut_ptr();
|
|
||||||
|
|
||||||
inner.add_to_free_list(page_ptr, 4096);
|
|
||||||
assert!(!inner.free_list.is_null());
|
|
||||||
|
|
||||||
let ptr = inner.alloc_from_free_list(64, 8);
|
|
||||||
assert!(!ptr.is_null());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn alloc_dealloc_roundtrip() {
|
|
||||||
let alloc = KosAllocator::new();
|
|
||||||
let inner = alloc.inner_mut();
|
|
||||||
|
|
||||||
let mut page = [0u8; 4096];
|
|
||||||
inner.add_to_free_list(page.as_mut_ptr(), 4096);
|
|
||||||
|
|
||||||
let layout = Layout::from_size_align(128, 8).unwrap();
|
|
||||||
let ptr = inner.alloc_from_free_list(128, 8);
|
|
||||||
assert!(!ptr.is_null());
|
|
||||||
|
|
||||||
inner.add_to_free_list(ptr, 128);
|
|
||||||
let ptr2 = inner.alloc_from_free_list(64, 8);
|
|
||||||
assert!(!ptr2.is_null());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn multiple_allocations_from_one_page() {
|
|
||||||
let alloc = KosAllocator::new();
|
|
||||||
let inner = alloc.inner_mut();
|
|
||||||
|
|
||||||
let mut page = [0u8; 4096];
|
|
||||||
inner.add_to_free_list(page.as_mut_ptr(), 4096);
|
|
||||||
|
|
||||||
let p1 = inner.alloc_from_free_list(256, 8);
|
|
||||||
let p2 = inner.alloc_from_free_list(256, 8);
|
|
||||||
let p3 = inner.alloc_from_free_list(256, 8);
|
|
||||||
|
|
||||||
assert!(!p1.is_null());
|
|
||||||
assert!(!p2.is_null());
|
|
||||||
assert!(!p3.is_null());
|
|
||||||
assert_ne!(p1, p2);
|
|
||||||
assert_ne!(p2, p3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn alignment_respected() {
|
|
||||||
let alloc = KosAllocator::new();
|
|
||||||
let inner = alloc.inner_mut();
|
|
||||||
|
|
||||||
let mut page = [0u8; 4096];
|
|
||||||
inner.add_to_free_list(page.as_mut_ptr(), 4096);
|
|
||||||
|
|
||||||
let ptr = inner.alloc_from_free_list(64, 64);
|
|
||||||
assert!(!ptr.is_null());
|
|
||||||
assert_eq!(ptr as usize % 64, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn exhausted_free_list_returns_null() {
|
|
||||||
let alloc = KosAllocator::new();
|
|
||||||
let inner = alloc.inner_mut();
|
|
||||||
|
|
||||||
let ptr = inner.alloc_from_free_list(64, 8);
|
|
||||||
assert!(ptr.is_null());
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
pub fn syscall0(_nr: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall1(_nr: usize, _a0: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall2(_nr: usize, _a0: usize, _a1: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall3(_nr: usize, _a0: usize, _a1: usize, _a2: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall4(_nr: usize, _a0: usize, _a1: usize, _a2: usize, _a3: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall5(_nr: usize, _a0: usize, _a1: usize, _a2: usize, _a3: usize, _a4: usize) -> usize {
|
|
||||||
0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn syscall_receive(_nr: usize, _a0: usize) -> (usize, usize, usize, usize) {
|
|
||||||
(0, 0, 0, 0)
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#[cfg(all(target_arch = "riscv64", target_os = "none"))]
|
|
||||||
mod riscv;
|
|
||||||
#[cfg(all(target_arch = "riscv64", target_os = "none"))]
|
|
||||||
pub use riscv::*;
|
|
||||||
|
|
||||||
#[cfg(not(target_os = "none"))]
|
|
||||||
mod mock;
|
|
||||||
#[cfg(not(target_os = "none"))]
|
|
||||||
pub use mock::*;
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
#[inline(always)]
|
|
||||||
pub fn syscall0(nr: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
lateout("a0") ret,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall1(nr: usize, a0: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => ret,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall2(nr: usize, a0: usize, a1: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => ret,
|
|
||||||
in("a1") a1,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall3(nr: usize, a0: usize, a1: usize, a2: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => ret,
|
|
||||||
in("a1") a1,
|
|
||||||
in("a2") a2,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall4(nr: usize, a0: usize, a1: usize, a2: usize, a3: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => ret,
|
|
||||||
in("a1") a1,
|
|
||||||
in("a2") a2,
|
|
||||||
in("a3") a3,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall5(nr: usize, a0: usize, a1: usize, a2: usize, a3: usize, a4: usize) -> usize {
|
|
||||||
let ret: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => ret,
|
|
||||||
in("a1") a1,
|
|
||||||
in("a2") a2,
|
|
||||||
in("a3") a3,
|
|
||||||
in("a4") a4,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn syscall_receive(nr: usize, a0: usize) -> (usize, usize, usize, usize) {
|
|
||||||
let r0: usize;
|
|
||||||
let r1: usize;
|
|
||||||
let r2: usize;
|
|
||||||
let r3: usize;
|
|
||||||
unsafe {
|
|
||||||
core::arch::asm!(
|
|
||||||
"ecall",
|
|
||||||
in("a7") nr,
|
|
||||||
inlateout("a0") a0 => r0,
|
|
||||||
lateout("a1") r1,
|
|
||||||
lateout("a2") r2,
|
|
||||||
lateout("a3") r3,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
(r0, r1, r2, r3)
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
#![no_std]
|
|
||||||
|
|
||||||
pub mod allocator;
|
|
||||||
mod arch;
|
|
||||||
pub mod syscall;
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
use crate::arch;
|
|
||||||
use types::syscall_abi::*;
|
|
||||||
use types::address::{EntryPoint, StackPointer, VirtualAddress};
|
|
||||||
use types::bounded::{CapSlot, PageCount};
|
|
||||||
use types::id::ProcessId;
|
|
||||||
use types::permission::PermissionSet;
|
|
||||||
use types::time::Ticks;
|
|
||||||
|
|
||||||
pub fn exit() -> ! {
|
|
||||||
arch::syscall0(SYS_EXIT);
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn exit_thread() -> ! {
|
|
||||||
arch::syscall0(SYS_EXIT_THREAD);
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn yield_now() {
|
|
||||||
arch::syscall0(SYS_YIELD);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn halt() -> ! {
|
|
||||||
arch::syscall0(SYS_HALT);
|
|
||||||
loop {}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_time() -> Ticks {
|
|
||||||
Ticks::from_raw(arch::syscall0(SYS_GET_TIME) as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_process_id() -> ProcessId {
|
|
||||||
ProcessId::from_raw(arch::syscall0(SYS_GET_PROCESS_ID) as u16)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_process(create_cap: CapSlot) -> Option<CapSlot> {
|
|
||||||
let r = arch::syscall1(SYS_CREATE_PROCESS, create_cap.value() as usize);
|
|
||||||
if r == usize::MAX { None } else { CapSlot::new(r as u8) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_endpoint() -> Option<CapSlot> {
|
|
||||||
let r = arch::syscall0(SYS_CREATE_ENDPOINT);
|
|
||||||
if r == usize::MAX { None } else { CapSlot::new(r as u8) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_thread(entry: EntryPoint, stack: StackPointer) -> usize {
|
|
||||||
arch::syscall2(SYS_SPAWN_THREAD, entry.raw(), stack.raw())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn spawn_thread_in(process_cap: CapSlot, entry: EntryPoint, stack: StackPointer) -> usize {
|
|
||||||
arch::syscall3(SYS_SPAWN_THREAD_IN, process_cap.value() as usize, entry.raw(), stack.raw())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn request_pages(count: PageCount) -> Option<VirtualAddress> {
|
|
||||||
let r = arch::syscall1(SYS_REQUEST_PAGES, count.value() as usize);
|
|
||||||
if r == usize::MAX { None } else { Some(VirtualAddress::from_raw(r)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn map_page(process_cap: CapSlot, src_va: VirtualAddress, dst_va: VirtualAddress, executable: bool) -> bool {
|
|
||||||
arch::syscall4(SYS_MAP_PAGE, process_cap.value() as usize, src_va.raw(), dst_va.raw(), executable as usize) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn send(endpoint: CapSlot, w0: usize, w1: usize, w2: usize, w3: usize) -> usize {
|
|
||||||
arch::syscall5(SYS_SEND, endpoint.value() as usize, w0, w1, w2, w3)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn receive(endpoint: CapSlot) -> (usize, usize, usize, usize) {
|
|
||||||
arch::syscall_receive(SYS_RECEIVE, endpoint.value() as usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn delegate(slot: CapSlot, to: CapSlot, permissions: PermissionSet) -> bool {
|
|
||||||
arch::syscall3(SYS_DELEGATE, slot.value() as usize, to.value() as usize, permissions.bits() as usize) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kill(process_cap: CapSlot) -> bool {
|
|
||||||
arch::syscall1(SYS_KILL, process_cap.value() as usize) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn revoke(slot: CapSlot) -> bool {
|
|
||||||
arch::syscall1(SYS_REVOKE, slot.value() as usize) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn debug_putchar(byte: u8) {
|
|
||||||
arch::syscall1(SYS_DEBUG_PUTCHAR, byte as usize);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user