Skip to content

Commit c165bed

Browse files
committed
add panic, stdio, and alloc support to armv7a-vex-v5
1 parent e517385 commit c165bed

File tree

6 files changed

+201
-4
lines changed

6 files changed

+201
-4
lines changed

compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ I'm not sure why subtracting anything is necessary, but it fixes memory permissi
1818
__heap_end = __cold_end - __stack_length - 0x1000;
1919

2020
SECTIONS {
21-
.code_signature {
21+
.code_signature : {
2222
KEEP(*(.code_signature))
2323
. = __cold_start + 0x20;
2424
} > COLD

library/panic_abort/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
5151
all(target_vendor = "fortanix", target_env = "sgx"),
5252
target_os = "xous",
5353
target_os = "uefi",
54+
target_os = "vexos",
5455
))] {
5556
unsafe fn abort() -> ! {
5657
// call std::sys::abort_internal

library/std/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ path = "../windows_targets"
6868
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
6969
rand_xorshift = "0.3.0"
7070

71-
[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "xous", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
71+
[target.'cfg(any(all(target_family = "wasm", target_os = "unknown"), target_os = "vexos", target_os = "xous", all(target_vendor = "fortanix", target_env = "sgx")))'.dependencies]
7272
dlmalloc = { version = "0.2.4", features = ['rustc-dep-of-std'] }
7373

7474
[target.x86_64-fortanix-unknown-sgx.dependencies]
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
use crate::{
2+
alloc::{GlobalAlloc, Layout, System},
3+
ptr,
4+
sync::atomic::{AtomicBool, Ordering},
5+
};
6+
7+
static mut DLMALLOC: dlmalloc::Dlmalloc<Vexos> = dlmalloc::Dlmalloc::new_with_allocator(Vexos);
8+
9+
extern "C" {
10+
static mut __heap_start: u8;
11+
static mut __heap_end: u8;
12+
}
13+
14+
struct Vexos;
15+
16+
unsafe impl dlmalloc::Allocator for Vexos {
17+
/// Allocs system resources
18+
fn alloc(&self, _size: usize) -> (*mut u8, usize, u32) {
19+
static INIT: AtomicBool = AtomicBool::new(false);
20+
21+
if !INIT.swap(true, Ordering::Relaxed) {
22+
unsafe {
23+
(
24+
ptr::addr_of_mut!(__heap_start).cast(),
25+
ptr::addr_of!(__heap_end).byte_offset_from(ptr::addr_of!(__heap_start)) as _,
26+
0,
27+
)
28+
}
29+
} else {
30+
(ptr::null_mut(), 0, 0)
31+
}
32+
}
33+
34+
fn remap(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize, _can_move: bool) -> *mut u8 {
35+
ptr::null_mut()
36+
}
37+
38+
fn free_part(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize) -> bool {
39+
false
40+
}
41+
42+
fn free(&self, _ptr: *mut u8, _size: usize) -> bool {
43+
return false;
44+
}
45+
46+
fn can_release_part(&self, _flags: u32) -> bool {
47+
false
48+
}
49+
50+
fn allocates_zeros(&self) -> bool {
51+
false
52+
}
53+
54+
fn page_size(&self) -> usize {
55+
0x1000
56+
}
57+
}
58+
59+
#[stable(feature = "alloc_system_type", since = "1.28.0")]
60+
unsafe impl GlobalAlloc for System {
61+
#[inline]
62+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
63+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
64+
// Calling malloc() is safe because preconditions on this function match the trait method preconditions.
65+
let _lock = lock::lock();
66+
unsafe { DLMALLOC.malloc(layout.size(), layout.align()) }
67+
}
68+
69+
#[inline]
70+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
71+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
72+
// Calling calloc() is safe because preconditions on this function match the trait method preconditions.
73+
let _lock = lock::lock();
74+
unsafe { DLMALLOC.calloc(layout.size(), layout.align()) }
75+
}
76+
77+
#[inline]
78+
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
79+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
80+
// Calling free() is safe because preconditions on this function match the trait method preconditions.
81+
let _lock = lock::lock();
82+
unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) }
83+
}
84+
85+
#[inline]
86+
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
87+
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
88+
// Calling realloc() is safe because preconditions on this function match the trait method preconditions.
89+
let _lock = lock::lock();
90+
unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) }
91+
}
92+
}
93+
94+
mod lock {
95+
#[inline]
96+
pub fn lock() {} // we don't have threads, which makes this real easy
97+
}

library/std/src/sys/pal/vexos/mod.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#[path = "../unsupported/alloc.rs"]
21
pub mod alloc;
32
#[path = "../unsupported/args.rs"]
43
pub mod args;
@@ -16,7 +15,6 @@ pub mod os;
1615
pub mod pipe;
1716
#[path = "../unsupported/process.rs"]
1817
pub mod process;
19-
#[path = "../unsupported/stdio.rs"]
2018
pub mod stdio;
2119
#[path = "../unsupported/thread.rs"]
2220
pub mod thread;
@@ -29,3 +27,18 @@ pub mod time;
2927
#[deny(unsafe_op_in_unsafe_fn)]
3028
mod common;
3129
pub use common::*;
30+
31+
// This function is needed by the panic runtime. The symbol is named in
32+
// pre-link args for the target specification, so keep that in sync.
33+
#[cfg(not(test))]
34+
#[no_mangle]
35+
// NB. used by both libunwind and libpanic_abort
36+
pub extern "C" fn __rust_abort() -> ! {
37+
unsafe {
38+
vex_sdk::vexSystemExitRequest();
39+
}
40+
41+
loop {
42+
crate::hint::spin_loop()
43+
}
44+
}
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use crate::io;
2+
3+
pub struct Stdin(());
4+
pub struct Stdout(());
5+
pub struct Stderr(());
6+
7+
const STDIO_CHANNEL: u32 = 1;
8+
9+
impl Stdin {
10+
pub const fn new() -> Stdin {
11+
Stdin(())
12+
}
13+
}
14+
15+
impl io::Read for Stdin {
16+
fn read(&mut self, mut buf: &mut [u8]) -> io::Result<usize> {
17+
let mut written = 0;
18+
19+
while let Some((out_byte, new_buf)) = buf.split_first_mut() {
20+
buf = new_buf;
21+
22+
let byte = unsafe { vex_sdk::vexSerialReadChar(STDIO_CHANNEL) };
23+
if byte < 0 {
24+
break;
25+
}
26+
27+
*out_byte = byte as u8;
28+
written += 1;
29+
}
30+
31+
Ok(written)
32+
}
33+
}
34+
35+
impl Stdout {
36+
pub const fn new() -> Stdout {
37+
Stdout(())
38+
}
39+
}
40+
41+
impl io::Write for Stdout {
42+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
43+
let written =
44+
unsafe { vex_sdk::vexSerialWriteBuffer(STDIO_CHANNEL, buf.as_ptr(), buf.len() as u32) };
45+
46+
if written < 0 {
47+
return Err(io::Error::new(io::ErrorKind::Other, "Internal write error occurred."));
48+
}
49+
50+
Ok(written as usize)
51+
}
52+
53+
fn flush(&mut self) -> io::Result<()> {
54+
unsafe {
55+
vex_sdk::vexTasksRun();
56+
}
57+
58+
Ok(())
59+
}
60+
}
61+
62+
impl Stderr {
63+
pub const fn new() -> Stderr {
64+
Stderr(())
65+
}
66+
}
67+
68+
impl io::Write for Stderr {
69+
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
70+
Ok(buf.len())
71+
}
72+
73+
fn flush(&mut self) -> io::Result<()> {
74+
Ok(())
75+
}
76+
}
77+
78+
pub const STDIN_BUF_SIZE: usize = 0;
79+
80+
pub fn is_ebadf(_err: &io::Error) -> bool {
81+
true
82+
}
83+
84+
pub fn panic_output() -> Option<impl io::Write> {
85+
Some(Stdout::new())
86+
}

0 commit comments

Comments
 (0)