Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add armv7a-vex-v5 tier three target #131530

Closed
wants to merge 72 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
72 commits
Select commit Hold shift + click to select a range
5b5f0a7
add armv7a-vex-v5 target
max-niederman May 28, 2024
266d1b6
add (shimmed) std support for armv7a-vex-v5
max-niederman May 28, 2024
83f35f3
add panic, stdio, and alloc support to armv7a-vex-v5
max-niederman May 28, 2024
56084eb
fix linker script and call main
max-niederman May 30, 2024
c204550
zero out bss section in _start
max-niederman Jul 17, 2024
c684a49
use static TLS implementation on vexos
max-niederman Jul 17, 2024
cdbfde6
make minor improvements to linker script
max-niederman Jul 17, 2024
5f8ee0c
enable stdio and fix stdout flushing
max-niederman Jul 18, 2024
a5403ca
add: `Instant` implementation
Gavin-Niederman Jul 18, 2024
d8c32e9
remove broken cleanup
max-niederman Jul 18, 2024
f5125f6
fix `.code_signature` section error
Tropix126 Jul 18, 2024
ac5f552
move `.code_signature` section into `.text`
Tropix126 Jul 18, 2024
bc07881
adjust `armv7a-vex-v5` target features for more aggressive hardware o…
Tropix126 Jul 18, 2024
170ba62
switch `llvm_target` to use ARM hard-float abi
Tropix126 Jul 18, 2024
80b1d36
add `env` implementation for `vexos` PAL
Tropix126 Jul 18, 2024
2855b31
feat: experimental fs support
Gavin-Niederman Jul 18, 2024
9aeeaa0
add support for more missing file operations
Tropix126 Jul 18, 2024
4f59642
feat: file writes vectored writes and vectored reads
Gavin-Niederman Jul 18, 2024
1900699
add helper for mapping FRESULT values
Tropix126 Jul 21, 2024
92d44bc
add: try_file_exists and stat
Gavin-Niederman Jul 21, 2024
62b6344
add: fileattr functions
Gavin-Niederman Jul 21, 2024
cf90d39
fix: check current position in file when getting size
Gavin-Niederman Jul 21, 2024
ff1aaf8
refactor: pseudorandom hashmap keys
Gavin-Niederman Jul 21, 2024
5e78476
fix: support File::file_attr and dissalow read and write mode at the …
Gavin-Niederman Jul 22, 2024
a5b9f71
feat: seek implementation
Gavin-Niederman Jul 22, 2024
1878f62
feat: almost working directory reading
Gavin-Niederman Jul 23, 2024
0aff419
fix: remove trailing slashes sooner
Gavin-Niederman Jul 23, 2024
0e0579a
remove test code and document filesystem quirks
Tropix126 Jul 27, 2024
ea7507e
add default code signature, ensure stdout flush
Tropix126 Aug 4, 2024
77e03a9
add platform docs
Tropix126 Aug 4, 2024
1581d08
adjust wording and fix typos in target documentation
Tropix126 Aug 4, 2024
8a69bd7
update PAL and add `check-cfg` override for `target_os`
Tropix126 Aug 5, 2024
1dbfada
add additional information to target spec and supporting docs
Tropix126 Aug 5, 2024
f39ea4a
fix `EXE_SUFFFIX` to use dot
Tropix126 Aug 9, 2024
77ddf8d
fix: use correct code signature default values
Tropix126 Aug 17, 2024
b6b3789
don't compile with `+thumb-mode` feature for now
Tropix126 Aug 21, 2024
b1671f1
properly flush serial on abort
Tropix126 Sep 6, 2024
3d0f59f
clarify documentation regarding cargo-v5, adjust `SystemTime` panic m…
Tropix126 Sep 7, 2024
ace69e6
use aapcs as system abi
max-niederman Oct 9, 2024
ea04c92
fix stack corruptions in startup routine
max-niederman Oct 9, 2024
f5237d6
fix thread locals
max-niederman Oct 9, 2024
e0e1eba
implement (shimmed) std::random
max-niederman Oct 9, 2024
e183779
fix allocation
max-niederman Oct 9, 2024
c492684
update linkerscript to include unwinding-related sections
Tropix126 Oct 11, 2024
84dcb23
format target doc and reorder maintainer list
max-niederman Oct 11, 2024
097d792
bump vex-sdk version and allow vex-sdk to be a stdlib dep
max-niederman Oct 11, 2024
6c2287c
add assembly test for armv7a-vex-v5
max-niederman Oct 11, 2024
b6d41fa
add armv7a-vex-v5 target docs to summary
max-niederman Oct 11, 2024
0d441ab
better document the is_like_vexos property of TargetOptions
max-niederman Oct 11, 2024
7bb6a04
detail summary of armv7a-vex-v5's target support
max-niederman Oct 11, 2024
a9ca387
add more descriptive comments to the `armv7a-vex-v5` linkerscript
Tropix126 Oct 13, 2024
24e381c
add `"v5"` target env armv7a-vex-v5 target spec
Tropix126 Oct 15, 2024
d11d208
implement `Stderr` in vexos PAL
Tropix126 Oct 23, 2024
1660bc6
run VEXos cpu1 scheduler while waiting for abort
Tropix126 Oct 23, 2024
508177c
update to `vex-sdk` 0.23.0
Tropix126 Oct 23, 2024
4d95d1f
add rudimentary implementation of `Thread::sleep` and `Thread::yield_…
Tropix126 Oct 25, 2024
034467f
fix broken reference to Instant in pal
max-niederman Oct 30, 2024
ed57739
switch to `+vfp3d16` LLVM feature in `armv7a-vex-v5`
Tropix126 Nov 11, 2024
a4701ce
fix and clean up comments surrounding file seeking
Tropix126 Dec 23, 2024
33f5078
add private unit to all pub fs types in vexos PAL
Tropix126 Dec 23, 2024
7168feb
treat all `io::Error`s as non-EBADF in vexos
Tropix126 Dec 23, 2024
8239a82
adjust error message for `FRESULT::FR_INT_ERR`
Tropix126 Dec 23, 2024
0b7aa15
bump `vex-sdk` to 0.26.0
Tropix126 Dec 23, 2024
fd8d110
update libstd lockfile
Tropix126 Dec 23, 2024
f76ae6f
fix circular dependency on cc-rs using a temporary patched version of…
max-niederman Jan 1, 2025
c0b0879
add unsupported file_lock functions
max-niederman Jan 1, 2025
08ace18
fix mistakes in fs PAL
max-niederman Jan 1, 2025
9f5c3f7
add `llvm_floatabi` to armv7a-vex-v5 spec
Tropix126 Jan 2, 2025
2081cf5
serialize `is_like_vexos` in target json specs
doinkythederp Jan 2, 2025
d0d1fd9
ensure `arm` arch before adjusting VEXos system ABI to `aapcs`
doinkythederp Jan 2, 2025
ee12faa
bless tests, add `armv7a-vex-v5` to assembly tests
Tropix126 Jan 25, 2025
d9a1349
backlink to relevant cleanup issues in FIXMEs
Tropix126 Jan 26, 2025
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
2 changes: 2 additions & 0 deletions compiler/rustc_target/src/spec/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ impl Target {
key!(is_like_msvc, bool);
key!(is_like_wasm, bool);
key!(is_like_android, bool);
key!(is_like_vexos, bool);
key!(default_dwarf_version, u32);
key!(allows_weak_linkage, bool);
key!(has_rpath, bool);
Expand Down Expand Up @@ -746,6 +747,7 @@ impl ToJson for Target {
target_option_val!(is_like_msvc);
target_option_val!(is_like_wasm);
target_option_val!(is_like_android);
target_option_val!(is_like_vexos);
target_option_val!(default_dwarf_version);
target_option_val!(allows_weak_linkage);
target_option_val!(has_rpath);
Expand Down
9 changes: 9 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,8 @@ supported_targets! {

("armv7-sony-vita-newlibeabihf", armv7_sony_vita_newlibeabihf),

("armv7a-vex-v5", armv7a_vex_v5),

("armv7-unknown-linux-uclibceabi", armv7_unknown_linux_uclibceabi),
("armv7-unknown-linux-uclibceabihf", armv7_unknown_linux_uclibceabihf),

Expand Down Expand Up @@ -2336,6 +2338,9 @@ pub struct TargetOptions {
pub is_like_wasm: bool,
/// Whether a target toolchain is like Android, implying a Linux kernel and a Bionic libc
pub is_like_android: bool,
/// Whether a target toolchain is like VEXos, the operating system used by the VEX Robotics V5 Brain.
/// Introduced for the `armv7a-vex-v5` target.
pub is_like_vexos: bool,
/// Default supported version of DWARF on this platform.
/// Useful because some platforms (osx, bsd) only want up to DWARF2.
pub default_dwarf_version: u32,
Expand Down Expand Up @@ -2708,6 +2713,7 @@ impl Default for TargetOptions {
is_like_msvc: false,
is_like_wasm: false,
is_like_android: false,
is_like_vexos: false,
default_dwarf_version: 4,
allows_weak_linkage: true,
has_rpath: false,
Expand Down Expand Up @@ -2815,6 +2821,9 @@ impl Target {
Abi::System { unwind } if self.is_like_windows && self.arch == "x86" && !c_variadic => {
Abi::Stdcall { unwind }
}
Abi::System { unwind } if self.is_like_vexos && self.arch == "arm" && !c_variadic => {
Abi::Aapcs { unwind }
}
Abi::System { unwind } => Abi::C { unwind },
Abi::EfiApi if self.arch == "arm" => Abi::Aapcs { unwind: false },
Abi::EfiApi if self.arch == "x86_64" => Abi::Win64 { unwind: false },
Expand Down
41 changes: 41 additions & 0 deletions compiler/rustc_target/src/spec/targets/armv7a_vex_v5.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::spec::{
Cc, FloatAbi, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions,
};

const LINK_SCRIPT: &str = include_str!("./armv7a_vex_v5_linker_script.ld");

pub(crate) fn target() -> Target {
Target {
llvm_target: "armv7a-none-eabihf".into(),
metadata: crate::spec::TargetMetadata {
description: Some("Armv7-A Cortex-A9 VEX V5 Brain, VEXos".into()),
tier: Some(3),
host_tools: Some(false),
std: Some(true),
},
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),
options: TargetOptions {
llvm_floatabi: Some(FloatAbi::Hard),
os: "vexos".into(),
is_like_vexos: true,
vendor: "vex".into(),
env: "v5".into(),
cpu: "cortex-a9".into(),
abi: "eabihf".into(),
features: "+v7,+neon,+vfp3d16,+thumb2".into(),
linker: Some("rust-lld".into()),
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
link_script: Some(LINK_SCRIPT.into()),
panic_strategy: PanicStrategy::Abort,
relocation_model: RelocModel::Static,
c_enum_min_bits: Some(8),
max_atomic_width: Some(64),
disable_redzone: true,
emit_debug_gdb_scripts: false,
has_thumb_interworking: true,
..Default::default()
},
}
}
100 changes: 100 additions & 0 deletions compiler/rustc_target/src/spec/targets/armv7a_vex_v5_linker_script.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
OUTPUT_FORMAT("elf32-littlearm")

ENTRY(_boot)

__user_ram_start = 0x03800000;
__user_ram_length = 0x04800000;
__user_ram_end = __user_ram_start + __user_ram_length;

__code_signature_length = 0x20;

__stack_length = 0x400000;
__heap_end = __user_ram_end - __stack_length;

/* see https://github.com/llvm/llvm-project/blob/main/libunwind/src/AddressSpace.hpp#L78 */
__eh_frame_hdr_start = SIZEOF(.eh_frame_hdr) > 0 ? ADDR(.eh_frame_hdr) : 0;
__eh_frame_hdr_end = SIZEOF(.eh_frame_hdr) > 0 ? . : 0;

MEMORY {
USER_RAM : ORIGIN = __user_ram_start, LENGTH = __user_ram_length
}

SECTIONS {
/*
* VEXos expects program binaries to have a 32-byte header called a "code signature",
* at their start, which tells the OS that we are a valid program and configures some
* miscellaneous startup behavior.
*
* This section is then initialized as a weak symbol in our PAL.
*/
.code_signature : {
KEEP(*(.code_signature))
. = __user_ram_start + __code_signature_length;
} > USER_RAM

.text : {
*(.boot)
*(.text .text.*)
} > USER_RAM

/* Global/uninitialized/static/constant data sections. */
.rodata : {
*(.rodata .rodata.*)
} > USER_RAM

.data : {
*(.data .data.*)
} > USER_RAM

.bss : {
__bss_start = .;
*(.bss .bss.*)
__bss_end = .;
} > USER_RAM

/*
* These sections are added by the compiler in some cases to facilitate stack unwinding.
* __eh_frame_start and similar symbols are used by libunwind.
*/
.eh_frame_hdr : {
KEEP(*(.eh_frame_hdr))
} > USER_RAM

.eh_frame : {
__eh_frame_start = .;
KEEP(*(.eh_frame))
__eh_frame_end = .;
} > USER_RAM

.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
__exidx_end = .;
} > USER_RAM

.ARM.extab : {
__extab_start = .;
*(.ARM.extab*)
__extab_end = .;
} > USER_RAM

/* Active memory regions for the stack/heap. */
.heap (NOLOAD) : ALIGN(4) {
__heap_start = .;
. = __heap_end;
} > USER_RAM

.stack (NOLOAD) : ALIGN(8) {
__stack_bottom = .;
. += __stack_length;
__stack_top = .;
} > USER_RAM

/*
* `.ARM.attributes` contains arch metadata for compatibility purposes, but we
* only target one hardware configuration, meaning it'd just take up space.
*/
/DISCARD/ : {
*(.ARM.attributes*)
}
}
11 changes: 11 additions & 0 deletions library/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ dependencies = [
"rustc-demangle",
"std_detect",
"unwind",
"vex-sdk",
"wasi",
"windows-targets 0.0.0",
]
Expand Down Expand Up @@ -401,6 +402,16 @@ dependencies = [
"rustc-std-workspace-core",
]

[[package]]
name = "vex-sdk"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be1b586dd8546706564cf20c94bae51c8f9e4891d70360d3fb63d563350df3d1"
dependencies = [
"compiler_builtins",
"rustc-std-workspace-core",
]

[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
Expand Down
4 changes: 4 additions & 0 deletions library/panic_abort/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ compiler_builtins = "0.1.0"

[target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
libc = { version = "0.2", default-features = false }

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = ['cfg(target_os, values("vexos"))']
1 change: 1 addition & 0 deletions library/panic_abort/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
all(target_vendor = "fortanix", target_env = "sgx"),
target_os = "xous",
target_os = "uefi",
target_os = "vexos",
))] {
unsafe fn abort() -> ! {
// call std::sys::abort_internal
Expand Down
6 changes: 5 additions & 1 deletion library/std/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ path = "../windows_targets"
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
rand_xorshift = "0.3.0"

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

[target.x86_64-fortanix-unknown-sgx.dependencies]
Expand All @@ -85,6 +85,9 @@ wasi = { version = "0.11.0", features = [
r-efi = { version = "4.5.0", features = ['rustc-dep-of-std'] }
r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std'] }

[target.'cfg(target_os = "vexos")'.dependencies]
vex-sdk = { version = "0.26.0", features = ['rustc-dep-of-std'] }

[features]
backtrace = [
'addr2line/rustc-dep-of-std',
Expand Down Expand Up @@ -140,6 +143,7 @@ level = "warn"
check-cfg = [
'cfg(bootstrap)',
'cfg(target_arch, values("xtensa"))',
'cfg(target_os, values("vexos"))',
# std use #[path] imports to portable-simd `std_float` crate
# and to the `backtrace` crate which messes-up with Cargo list
# of declared features, we therefor expect any feature cfg
Expand Down
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ fn main() {
|| target_os == "zkvm"
|| target_os == "rtems"
|| target_os == "nuttx"
|| target_os == "vexos"

// See src/bootstrap/src/core/build_steps/synthetic_targets.rs
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/alloc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,5 +90,7 @@ cfg_if::cfg_if! {
mod xous;
} else if #[cfg(target_os = "zkvm")] {
mod zkvm;
} else if #[cfg(target_os = "vexos")] {
mod vexos;
}
}
98 changes: 98 additions & 0 deletions library/std/src/sys/alloc/vexos.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
#![allow(static_mut_refs)]

use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr;
use crate::sync::atomic::{AtomicBool, Ordering};

static mut DLMALLOC: dlmalloc::Dlmalloc<Vexos> = dlmalloc::Dlmalloc::new_with_allocator(Vexos);

extern "C" {
static mut __heap_start: u8;
static mut __heap_end: u8;
}

struct Vexos;

unsafe impl dlmalloc::Allocator for Vexos {
/// Allocs system resources
fn alloc(&self, _size: usize) -> (*mut u8, usize, u32) {
static INIT: AtomicBool = AtomicBool::new(false);

if !INIT.swap(true, Ordering::Relaxed) {
unsafe {
(
ptr::addr_of_mut!(__heap_start).cast(),
ptr::addr_of!(__heap_end).byte_offset_from(ptr::addr_of!(__heap_start)) as _,
0,
)
}
} else {
(ptr::null_mut(), 0, 0)
}
}

fn remap(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize, _can_move: bool) -> *mut u8 {
ptr::null_mut()
}

fn free_part(&self, _ptr: *mut u8, _oldsize: usize, _newsize: usize) -> bool {
false
}

fn free(&self, _ptr: *mut u8, _size: usize) -> bool {
false
}

fn can_release_part(&self, _flags: u32) -> bool {
false
}

fn allocates_zeros(&self) -> bool {
false
}

fn page_size(&self) -> usize {
0x1000
}
}

#[stable(feature = "alloc_system_type", since = "1.28.0")]
unsafe impl GlobalAlloc for System {
#[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
// Calling malloc() is safe because preconditions on this function match the trait method preconditions.
let _lock = lock::lock();
unsafe { DLMALLOC.malloc(layout.size(), layout.align()) }
}

#[inline]
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
// Calling calloc() is safe because preconditions on this function match the trait method preconditions.
let _lock = lock::lock();
unsafe { DLMALLOC.calloc(layout.size(), layout.align()) }
}

#[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
// Calling free() is safe because preconditions on this function match the trait method preconditions.
let _lock = lock::lock();
unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) }
}

#[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
// SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access.
// Calling realloc() is safe because preconditions on this function match the trait method preconditions.
let _lock = lock::lock();
unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) }
}
}

mod lock {
#[inline]
pub fn lock() {} // we don't have threads, which makes this real easy
}
workingjubilee marked this conversation as resolved.
Show resolved Hide resolved
3 changes: 3 additions & 0 deletions library/std/src/sys/pal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "zkvm")] {
mod zkvm;
pub use self::zkvm::*;
} else if #[cfg(target_os = "vexos")] {
mod vexos;
pub use self::vexos::*;
} else {
mod unsupported;
pub use self::unsupported::*;
Expand Down
9 changes: 9 additions & 0 deletions library/std/src/sys/pal/vexos/env.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub mod os {
pub const FAMILY: &str = "";
pub const OS: &str = "vexos";
pub const DLL_PREFIX: &str = "";
pub const DLL_SUFFIX: &str = "";
pub const DLL_EXTENSION: &str = "";
pub const EXE_SUFFIX: &str = ".bin";
pub const EXE_EXTENSION: &str = "bin";
}
Loading
Loading