Skip to content

Commit

Permalink
feat: ✨ Enable edition 2024
Browse files Browse the repository at this point in the history
  • Loading branch information
berkus committed Oct 5, 2024
1 parent 76c9a47 commit 4d78488
Show file tree
Hide file tree
Showing 22 changed files with 207 additions and 158 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ readme = "README.md"
license = "BlueOak-1.0.0"
categories = ["no-std", "embedded", "os"]
publish = false
edition = "2021"
edition = "2024"

[workspace.dependencies]
qemu-exit = "3.0"
Expand Down
2 changes: 2 additions & 0 deletions bin/chainboot/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
cargo-features = ["edition2024"]

[package]
name = "chainboot"
description = "Chain boot loader"
Expand Down
58 changes: 31 additions & 27 deletions bin/chainboot/src/boot.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Make first function small enough so that compiler doesn't try
// to crate a huge stack frame before we have a chance to set SP.
#[no_mangle]
#[link_section = ".text.chainboot.entry"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.chainboot.entry")]
pub unsafe extern "C" fn _start() -> ! {
use {
aarch64_cpu::registers::{MPIDR_EL1, SP},
Expand All @@ -18,18 +18,18 @@ pub unsafe extern "C" fn _start() -> ! {
endless_sleep()
}

extern "Rust" {
unsafe extern "Rust" {
// Stack top
static __boot_core_stack_end_exclusive: UnsafeCell<()>;
}
// Set stack pointer.
SP.set(__boot_core_stack_end_exclusive.get() as u64);
SP.set(unsafe { __boot_core_stack_end_exclusive.get() } as u64);

reset();
unsafe { reset() };
}

#[no_mangle]
#[link_section = ".text.chainboot"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.chainboot")]
pub unsafe extern "C" fn reset() -> ! {
use core::{
cell::UnsafeCell,
Expand All @@ -38,7 +38,7 @@ pub unsafe extern "C" fn reset() -> ! {

// These are a problem, because they are not interpreted as constants here.
// Subsequently, this code tries to read values from not-yet-existing data locations.
extern "Rust" {
unsafe extern "Rust" {
// Boundaries of the .bss section, provided by the linker script
static __BSS_START: UnsafeCell<()>;
static __BSS_SIZE_U64S: UnsafeCell<()>;
Expand All @@ -60,23 +60,27 @@ pub unsafe extern "C" fn reset() -> ! {
// __binary_nonzero_vma.get() as *mut u64,
// __binary_nonzero_vma_end_exclusive.get() as usize - __binary_nonzero_vma.get() as usize,
// );
let binary_size =
__binary_nonzero_vma_end_exclusive.get() as usize - __binary_nonzero_vma.get() as usize;
local_memcpy(
__binary_nonzero_vma.get() as *mut u8,
__binary_nonzero_lma.get() as *const u8,
binary_size,
);
let binary_size = unsafe { __binary_nonzero_vma_end_exclusive.get() } as usize
- unsafe { __binary_nonzero_vma.get() } as usize;
unsafe {
local_memcpy(
__binary_nonzero_vma.get() as *mut u8,
__binary_nonzero_lma.get() as *const u8,
binary_size,
)
};

// This tries to call memset() at a wrong linked address - the function is in relocated area!

// Zeroes the .bss section
// Emulate
// crate::stdmem::local_memset(__bss_start.get() as *mut u8, 0u8, __bss_size.get() as usize);
let bss = core::slice::from_raw_parts_mut(
__BSS_START.get() as *mut u64,
__BSS_SIZE_U64S.get() as usize,
);
let bss = unsafe {
core::slice::from_raw_parts_mut(
__BSS_START.get() as *mut u64,
__BSS_SIZE_U64S.get() as usize,
)
};
for i in bss {
*i = 0;
}
Expand All @@ -87,18 +91,18 @@ pub unsafe extern "C" fn reset() -> ! {
// Additionally, we assume that no statics are accessed before this point.
atomic::compiler_fence(Ordering::SeqCst);

let max_kernel_size =
__binary_nonzero_vma.get() as u64 - __boot_core_stack_end_exclusive.get() as u64;
crate::kernel_init(max_kernel_size)
let max_kernel_size = unsafe { __binary_nonzero_vma.get() } as u64
- unsafe { __boot_core_stack_end_exclusive.get() } as u64;
unsafe { crate::kernel_init(max_kernel_size) }
}

#[inline(always)]
#[link_section = ".text.chainboot"]
#[unsafe(link_section = ".text.chainboot")]
unsafe fn local_memcpy(mut dest: *mut u8, mut src: *const u8, n: usize) {
let dest_end = dest.add(n);
let dest_end = unsafe { dest.add(n) };
while dest < dest_end {
*dest = *src;
dest = dest.add(1);
src = src.add(1);
unsafe { *dest = *src };
dest = unsafe { dest.add(1) };
src = unsafe { src.add(1) };
}
}
8 changes: 4 additions & 4 deletions bin/chainboot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ unsafe fn kernel_init(max_kernel_size: u64) -> ! {
#[cfg(feature = "jtag")]
machine::debug::jtag::wait_debugger();

if let Err(x) = machine::platform::drivers::init() {
if let Err(x) = unsafe { machine::platform::drivers::init() } {
panic!("Error initializing platform drivers: {}", x);
}

// Initialize all device drivers.
machine::drivers::driver_manager().init_drivers_and_irqs();
unsafe { machine::drivers::driver_manager().init_drivers_and_irqs() };

// println! is usable from here on.

Expand All @@ -41,8 +41,8 @@ unsafe fn kernel_init(max_kernel_size: u64) -> ! {

// https://onlineasciitools.com/convert-text-to-ascii-art (FIGlet) with `cricket` font
const LOGO: &str = r#"
__ __ __ __
.----| |--.---.-|__.-----| |--.-----.-----| |_
__ __ __ __
.----| |--.---.-|__.-----| |--.-----.-----| |_
| __| | _ | | | _ | _ | _ | _|
|____|__|__|___._|__|__|__|_____|_____|_____|____|
"#;
Expand Down
2 changes: 2 additions & 0 deletions bin/chainofcommand/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
cargo-features = ["edition2024"]

[package]
name = "chainofcommand"
description = "Host server for chainboot"
Expand Down
2 changes: 2 additions & 0 deletions machine/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
cargo-features = ["edition2024"]

[package]
name = "machine"
description = "Vesper nanokernel shared code library, useful also for the chainboot loader."
Expand Down
40 changes: 21 additions & 19 deletions machine/src/arch/aarch64/cpu/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ macro_rules! entry {
($path:path) => {
/// # Safety
/// Only type-checks!
#[export_name = "main"]
#[unsafe(export_name = "main")]
#[inline(always)]
pub unsafe fn __main() -> ! {
// type check the given path
Expand All @@ -52,22 +52,22 @@ macro_rules! entry {
///
/// Totally unsafe! We're in the hardware land.
/// We assume that no statics are accessed before transition to main from reset() function.
#[no_mangle]
#[link_section = ".text.main.entry"]
#[unsafe(no_mangle)]
#[unsafe(link_section = ".text.main.entry")]
pub unsafe extern "C" fn _boot_cores() -> ! {
// Can't match values with dots in match, so use intermediate consts.
#[cfg(feature = "qemu")]
const EL3: u64 = CurrentEL::EL::EL3.value;
const EL2: u64 = CurrentEL::EL::EL2.value;
const EL1: u64 = CurrentEL::EL::EL1.value;

extern "Rust" {
unsafe extern "Rust" {
// Stack top
// Stack placed before first executable instruction
static __STACK_TOP: UnsafeCell<()>;
}
// Set stack pointer. Used in case we started in EL1.
SP.set(__STACK_TOP.get() as u64);
SP.set(unsafe { __STACK_TOP.get() } as u64);

shared_setup_and_enter_pre();

Expand All @@ -76,7 +76,7 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
#[cfg(feature = "qemu")]
EL3 => setup_and_enter_el1_from_el3(),
EL2 => setup_and_enter_el1_from_el2(),
EL1 => reset(),
EL1 => unsafe { reset() },
_ => endless_sleep(),
}
}
Expand All @@ -85,7 +85,7 @@ pub unsafe extern "C" fn _boot_cores() -> ! {
endless_sleep()
}

#[link_section = ".text.boot"]
#[unsafe(link_section = ".text.boot")]
#[inline(always)]
fn shared_setup_and_enter_pre() {
// Enable timer counter registers for EL1
Expand Down Expand Up @@ -116,10 +116,10 @@ fn shared_setup_and_enter_pre() {
// @todo disable VM bit to prevent stage 2 MMU translations
}

#[link_section = ".text.boot"]
#[unsafe(link_section = ".text.boot")]
#[inline]
fn shared_setup_and_enter_post() -> ! {
extern "Rust" {
unsafe extern "Rust" {
// Stack top
static __STACK_TOP: UnsafeCell<()>;
}
Expand All @@ -137,7 +137,7 @@ fn shared_setup_and_enter_post() -> ! {
/// Real hardware boot-up sequence.
///
/// Prepare and execute transition from EL2 to EL1.
#[link_section = ".text.boot"]
#[unsafe(link_section = ".text.boot")]
#[inline]
fn setup_and_enter_el1_from_el2() -> ! {
// Set Saved Program Status Register (EL2)
Expand Down Expand Up @@ -170,7 +170,7 @@ fn setup_and_enter_el1_from_el2() -> ! {
/// Prepare and execute transition from EL3 to EL1.
/// (from https://github.com/s-matyukevich/raspberry-pi-os/blob/master/docs/lesson02/rpi-os.md)
#[cfg(feature = "qemu")]
#[link_section = ".text.boot"]
#[unsafe(link_section = ".text.boot")]
#[inline]
fn setup_and_enter_el1_from_el3() -> ! {
// Set Secure Configuration Register (EL3)
Expand Down Expand Up @@ -205,9 +205,9 @@ fn setup_and_enter_el1_from_el3() -> ! {
/// We assume that no statics are accessed before transition to main from this function.
///
/// We are guaranteed to be in EL1 non-secure mode here.
#[link_section = ".text.boot"]
#[unsafe(link_section = ".text.boot")]
unsafe fn reset() -> ! {
extern "Rust" {
unsafe extern "Rust" {
// Boundaries of the .bss section, provided by the linker script.
static __BSS_START: UnsafeCell<()>;
static __BSS_SIZE_U64S: UnsafeCell<()>;
Expand All @@ -224,10 +224,12 @@ unsafe fn reset() -> ! {
// undesirable optimizations on them.
// So we use a pointer-and-a-size as described in provenance section.

let bss = slice::from_raw_parts_mut(
__BSS_START.get() as *mut u64,
__BSS_SIZE_U64S.get() as usize,
);
let bss = unsafe {
slice::from_raw_parts_mut(
__BSS_START.get() as *mut u64,
__BSS_SIZE_U64S.get() as usize,
)
};
for i in bss {
*i = 0;
}
Expand All @@ -238,9 +240,9 @@ unsafe fn reset() -> ! {
// Additionally, we assume that no statics are accessed before this point.
atomic::compiler_fence(Ordering::SeqCst);

extern "Rust" {
unsafe extern "Rust" {
fn main() -> !;
}

main()
unsafe { main() }
}
30 changes: 15 additions & 15 deletions machine/src/arch/aarch64/exception/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ struct ExceptionContext {
/// Prints verbose information about the exception and then panics.
///
/// Default pointer is configured in the linker script.
#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn default_exception_handler(exc: &ExceptionContext) {
panic!(
"Unexpected CPU Exception!\n\n\
Expand All @@ -117,17 +117,17 @@ extern "C" fn default_exception_handler(exc: &ExceptionContext) {
// Current, EL0
//------------------------------------------------------------------------------

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_el0_synchronous(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_el0_irq(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_el0_serror(_e: &mut ExceptionContext) {
panic!("Should not be here. Use of SP_EL0 in EL1 is not supported.")
}
Expand All @@ -136,7 +136,7 @@ extern "C" fn current_el0_serror(_e: &mut ExceptionContext) {
// Current, ELx
//------------------------------------------------------------------------------

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
#[cfg(feature = "test_build")]
{
Expand All @@ -152,13 +152,13 @@ extern "C" fn current_elx_synchronous(e: &mut ExceptionContext) {
default_exception_handler(e);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_elx_irq(_e: &mut ExceptionContext) {
let token = unsafe { &exception::asynchronous::IRQContext::new() };
exception::asynchronous::irq_manager().handle_pending_irqs(token);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn current_elx_serror(e: &mut ExceptionContext) {
default_exception_handler(e);
}
Expand All @@ -167,17 +167,17 @@ extern "C" fn current_elx_serror(e: &mut ExceptionContext) {
// Lower, AArch64
//------------------------------------------------------------------------------

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch64_synchronous(e: &mut ExceptionContext) {
default_exception_handler(e);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch64_irq(e: &mut ExceptionContext) {
default_exception_handler(e);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch64_serror(e: &mut ExceptionContext) {
default_exception_handler(e);
}
Expand All @@ -186,17 +186,17 @@ extern "C" fn lower_aarch64_serror(e: &mut ExceptionContext) {
// Lower, AArch32
//------------------------------------------------------------------------------

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch32_synchronous(e: &mut ExceptionContext) {
default_exception_handler(e);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch32_irq(e: &mut ExceptionContext) {
default_exception_handler(e);
}

#[no_mangle]
#[unsafe(no_mangle)]
extern "C" fn lower_aarch32_serror(e: &mut ExceptionContext) {
default_exception_handler(e);
}
Expand Down Expand Up @@ -354,8 +354,8 @@ pub fn current_privilege_level() -> (PrivilegeLevel, &'static str) {
/// adhere to the alignment and size constraints demanded by the ARMv8-A Architecture Reference
/// Manual.
pub fn handling_init() {
// Provided by vectors.S.
extern "Rust" {
// SAFETY: Provided by vectors.S.
unsafe extern "Rust" {
static __EXCEPTION_VECTORS_START: UnsafeCell<()>;
}

Expand Down
Loading

0 comments on commit 4d78488

Please sign in to comment.