From 4d7848814e790e707243e6e335fd4ba136a17ca5 Mon Sep 17 00:00:00 2001 From: Berkus Decker Date: Sat, 5 Oct 2024 03:24:13 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20Enable=20edition=202024?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.toml | 2 +- bin/chainboot/Cargo.toml | 2 + bin/chainboot/src/boot.rs | 58 +++++++------- bin/chainboot/src/main.rs | 8 +- bin/chainofcommand/Cargo.toml | 2 + machine/Cargo.toml | 2 + machine/src/arch/aarch64/cpu/boot.rs | 40 +++++----- machine/src/arch/aarch64/exception/mod.rs | 30 +++---- machine/src/debug/jtag.rs | 2 +- machine/src/drivers.rs | 4 +- machine/src/lib.rs | 7 +- machine/src/memory/mmu/mod.rs | 30 +++---- .../device_driver/arm/gicv2/mod.rs | 4 +- .../raspberrypi/device_driver/bcm/gpio.rs | 2 +- .../bcm/interrupt_controller/mod.rs | 2 +- .../device_driver/bcm/mini_uart.rs | 2 +- .../device_driver/bcm/pl011_uart.rs | 2 +- machine/src/platform/raspberrypi/drivers.rs | 80 ++++++++++++------- .../src/platform/raspberrypi/memory/mmu.rs | 74 +++++++++-------- .../src/platform/raspberrypi/memory/mod.rs | 2 +- nucleus/Cargo.toml | 2 + nucleus/src/main.rs | 8 +- 22 files changed, 207 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ed833d8f..fb168403 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/bin/chainboot/Cargo.toml b/bin/chainboot/Cargo.toml index f13af372..6972cf0a 100644 --- a/bin/chainboot/Cargo.toml +++ b/bin/chainboot/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["edition2024"] + [package] name = "chainboot" description = "Chain boot loader" diff --git a/bin/chainboot/src/boot.rs b/bin/chainboot/src/boot.rs index 6c1e4b0b..c1c44be0 100644 --- a/bin/chainboot/src/boot.rs +++ b/bin/chainboot/src/boot.rs @@ -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}, @@ -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, @@ -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<()>; @@ -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; } @@ -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) }; } } diff --git a/bin/chainboot/src/main.rs b/bin/chainboot/src/main.rs index a2039cac..fa5c33bb 100644 --- a/bin/chainboot/src/main.rs +++ b/bin/chainboot/src/main.rs @@ -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. @@ -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#" - __ __ __ __ - .----| |--.---.-|__.-----| |--.-----.-----| |_ + __ __ __ __ + .----| |--.---.-|__.-----| |--.-----.-----| |_ | __| | _ | | | _ | _ | _ | _| |____|__|__|___._|__|__|__|_____|_____|_____|____| "#; diff --git a/bin/chainofcommand/Cargo.toml b/bin/chainofcommand/Cargo.toml index c90517b0..2aeebb16 100644 --- a/bin/chainofcommand/Cargo.toml +++ b/bin/chainofcommand/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["edition2024"] + [package] name = "chainofcommand" description = "Host server for chainboot" diff --git a/machine/Cargo.toml b/machine/Cargo.toml index e57ea131..63a09386 100644 --- a/machine/Cargo.toml +++ b/machine/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["edition2024"] + [package] name = "machine" description = "Vesper nanokernel shared code library, useful also for the chainboot loader." diff --git a/machine/src/arch/aarch64/cpu/boot.rs b/machine/src/arch/aarch64/cpu/boot.rs index 28298bf8..eea9f5f6 100644 --- a/machine/src/arch/aarch64/cpu/boot.rs +++ b/machine/src/arch/aarch64/cpu/boot.rs @@ -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 @@ -52,8 +52,8 @@ 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")] @@ -61,13 +61,13 @@ pub unsafe extern "C" fn _boot_cores() -> ! { 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(); @@ -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(), } } @@ -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 @@ -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<()>; } @@ -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) @@ -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) @@ -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<()>; @@ -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; } @@ -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() } } diff --git a/machine/src/arch/aarch64/exception/mod.rs b/machine/src/arch/aarch64/exception/mod.rs index fa3c4936..b27e4009 100644 --- a/machine/src/arch/aarch64/exception/mod.rs +++ b/machine/src/arch/aarch64/exception/mod.rs @@ -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\ @@ -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.") } @@ -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")] { @@ -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); } @@ -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); } @@ -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); } @@ -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<()>; } diff --git a/machine/src/debug/jtag.rs b/machine/src/debug/jtag.rs index 1436b580..fcb59d81 100644 --- a/machine/src/debug/jtag.rs +++ b/machine/src/debug/jtag.rs @@ -5,7 +5,7 @@ use { core::ptr::{read_volatile, write_volatile}, }; -#[no_mangle] +#[unsafe(no_mangle)] static mut WAIT_FLAG: bool = true; /// Wait for debugger to attach. diff --git a/machine/src/drivers.rs b/machine/src/drivers.rs index dc844408..108f5576 100644 --- a/machine/src/drivers.rs +++ b/machine/src/drivers.rs @@ -170,7 +170,7 @@ where pub unsafe fn init_drivers_and_irqs(&self) { self.for_each_descriptor(|descriptor| { // 1. Initialize driver. - if let Err(x) = descriptor.device_driver.init() { + if let Err(x) = unsafe { descriptor.device_driver.init() } { panic!( "Error initializing driver: {}: {}", descriptor.device_driver.compatible(), @@ -180,7 +180,7 @@ where // 2. Call corresponding post init callback. if let Some(callback) = &descriptor.post_init_callback { - if let Err(x) = callback() { + if let Err(x) = unsafe { callback() } { panic!( "Error during driver post-init callback: {}: {}", descriptor.device_driver.compatible(), diff --git a/machine/src/lib.rs b/machine/src/lib.rs index cc1fd32b..d8146905 100644 --- a/machine/src/lib.rs +++ b/machine/src/lib.rs @@ -97,16 +97,17 @@ mod lib_tests { } /// Main for running tests. - #[no_mangle] + #[unsafe(no_mangle)] pub unsafe fn main() -> ! { exception::handling_init(); - let phys_kernel_tables_base_addr = match memory::mmu::kernel_map_binary() { + let phys_kernel_tables_base_addr = match unsafe { memory::mmu::kernel_map_binary() } { Err(string) => panic!("Error mapping kernel binary: {}", string), Ok(addr) => addr, }; - if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) { + if let Err(e) = unsafe { memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) } + { panic!("Enabling MMU failed: {}", e); } diff --git a/machine/src/memory/mmu/mod.rs b/machine/src/memory/mmu/mod.rs index 8fa8c6a7..41690fed 100644 --- a/machine/src/memory/mmu/mod.rs +++ b/machine/src/memory/mmu/mod.rs @@ -107,7 +107,7 @@ unsafe fn kernel_map_at_unchecked( attr: &AttributeFields, ) -> Result<(), &'static str> { platform::memory::mmu::kernel_translation_tables() - .write(|tables| tables.map_at(virt_region, phys_region, attr))?; + .write(|tables| unsafe { tables.map_at(virt_region, phys_region, attr) })?; if let Err(x) = mapping_record::kernel_add(name, virt_region, phys_region, attr) { warn!("{}", x); @@ -176,7 +176,7 @@ pub unsafe fn kernel_map_at( return Err("Attempt to manually map into MMIO region"); } - kernel_map_at_unchecked(name, virt_region, phys_region, attr)?; + unsafe { kernel_map_at_unchecked(name, virt_region, phys_region, attr)? }; Ok(()) } @@ -210,16 +210,18 @@ pub unsafe fn kernel_map_mmio( let virt_region = page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.alloc(num_pages))?; - kernel_map_at_unchecked( - name, - &virt_region, - &phys_region, - &AttributeFields { - mem_attributes: MemAttributes::Device, - acc_perms: AccessPermissions::ReadWrite, - execute_never: true, - }, - )?; + unsafe { + kernel_map_at_unchecked( + name, + &virt_region, + &phys_region, + &AttributeFields { + mem_attributes: MemAttributes::Device, + acc_perms: AccessPermissions::ReadWrite, + execute_never: true, + }, + )? + }; virt_region.start_addr() }; @@ -239,7 +241,7 @@ pub unsafe fn kernel_map_binary() -> Result, &'static str> { tables.phys_base_address() }); - platform::memory::mmu::kernel_map_binary()?; + unsafe { platform::memory::mmu::kernel_map_binary()? }; Ok(phys_kernel_tables_base_addr) } @@ -253,7 +255,7 @@ pub unsafe fn kernel_map_binary() -> Result, &'static str> { pub unsafe fn enable_mmu_and_caching( phys_tables_base_addr: Address, ) -> Result<(), MMUEnableError> { - arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr) + unsafe { arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr) } } /// Finish initialization of the MMU subsystem. diff --git a/machine/src/platform/raspberrypi/device_driver/arm/gicv2/mod.rs b/machine/src/platform/raspberrypi/device_driver/arm/gicv2/mod.rs index 9b49c413..1b1c7c6f 100644 --- a/machine/src/platform/raspberrypi/device_driver/arm/gicv2/mod.rs +++ b/machine/src/platform/raspberrypi/device_driver/arm/gicv2/mod.rs @@ -131,8 +131,8 @@ impl GICv2 { gicc_mmio_start_addr: Address, ) -> Self { Self { - gicd: gicd::GICD::new(gicd_mmio_start_addr), - gicc: gicc::GICC::new(gicc_mmio_start_addr), + gicd: unsafe { gicd::GICD::new(gicd_mmio_start_addr) }, + gicc: unsafe { gicc::GICC::new(gicc_mmio_start_addr) }, handler_table: InitStateLock::new([None; IRQNumber::MAX_INCLUSIVE + 1]), } } diff --git a/machine/src/platform/raspberrypi/device_driver/bcm/gpio.rs b/machine/src/platform/raspberrypi/device_driver/bcm/gpio.rs index cbef79c7..b55bfa90 100644 --- a/machine/src/platform/raspberrypi/device_driver/bcm/gpio.rs +++ b/machine/src/platform/raspberrypi/device_driver/bcm/gpio.rs @@ -218,7 +218,7 @@ impl GPIO { /// Unsafe, duh! pub const unsafe fn new(mmio_base_addr: Address) -> Self { Self { - inner: IRQSafeNullLock::new(GPIOInner::new(mmio_base_addr)), + inner: IRQSafeNullLock::new(unsafe { GPIOInner::new(mmio_base_addr) }), } } diff --git a/machine/src/platform/raspberrypi/device_driver/bcm/interrupt_controller/mod.rs b/machine/src/platform/raspberrypi/device_driver/bcm/interrupt_controller/mod.rs index b2819d7d..3b4f6009 100644 --- a/machine/src/platform/raspberrypi/device_driver/bcm/interrupt_controller/mod.rs +++ b/machine/src/platform/raspberrypi/device_driver/bcm/interrupt_controller/mod.rs @@ -96,7 +96,7 @@ impl InterruptController { /// - The user must ensure to provide a correct MMIO start address. pub const unsafe fn new(periph_mmio_start_addr: Address) -> Self { Self { - periph: peripheral_ic::PeripheralIC::new(periph_mmio_start_addr), + periph: unsafe { peripheral_ic::PeripheralIC::new(periph_mmio_start_addr) }, } } } diff --git a/machine/src/platform/raspberrypi/device_driver/bcm/mini_uart.rs b/machine/src/platform/raspberrypi/device_driver/bcm/mini_uart.rs index 459d6a40..9292f943 100644 --- a/machine/src/platform/raspberrypi/device_driver/bcm/mini_uart.rs +++ b/machine/src/platform/raspberrypi/device_driver/bcm/mini_uart.rs @@ -198,7 +198,7 @@ impl MiniUart { /// - The user must ensure to provide a correct MMIO start address. pub const unsafe fn new(mmio_base_addr: Address) -> Self { Self { - inner: IRQSafeNullLock::new(MiniUartInner::new(mmio_base_addr)), + inner: IRQSafeNullLock::new(unsafe { MiniUartInner::new(mmio_base_addr) }), } } diff --git a/machine/src/platform/raspberrypi/device_driver/bcm/pl011_uart.rs b/machine/src/platform/raspberrypi/device_driver/bcm/pl011_uart.rs index c9836f25..9d6aa163 100644 --- a/machine/src/platform/raspberrypi/device_driver/bcm/pl011_uart.rs +++ b/machine/src/platform/raspberrypi/device_driver/bcm/pl011_uart.rs @@ -325,7 +325,7 @@ impl PL011Uart { /// - The user must ensure to provide a correct MMIO start address. pub const unsafe fn new(mmio_base_addr: Address) -> Self { Self { - inner: IRQSafeNullLock::new(PL011UartInner::new(mmio_base_addr)), + inner: IRQSafeNullLock::new(unsafe { PL011UartInner::new(mmio_base_addr) }), } } diff --git a/machine/src/platform/raspberrypi/drivers.rs b/machine/src/platform/raspberrypi/drivers.rs index 86d3e56d..97220370 100644 --- a/machine/src/platform/raspberrypi/drivers.rs +++ b/machine/src/platform/raspberrypi/drivers.rs @@ -39,9 +39,11 @@ pub unsafe fn init() -> Result<(), &'static str> { } #[cfg(not(feature = "noserial"))] - driver_uart()?; - driver_gpio()?; - driver_interrupt_controller()?; + unsafe { + driver_uart()? + }; + unsafe { driver_gpio()? }; + unsafe { driver_interrupt_controller()? }; INIT_DONE.store(true, Ordering::Relaxed); Ok(()) @@ -79,11 +81,14 @@ static mut INTERRUPT_CONTROLLER: MaybeUninit = MaybeUninit /// This must be called only after successful init of the memory subsystem. unsafe fn instantiate_uart() -> Result<(), &'static str> { let mmio_descriptor = MMIODescriptor::new(mmio::PL011_UART_BASE, mmio::PL011_UART_SIZE); - let virt_addr = - memory::mmu::kernel_map_mmio(device_driver::PL011Uart::COMPATIBLE, &mmio_descriptor)?; + let virt_addr = unsafe { + memory::mmu::kernel_map_mmio(device_driver::PL011Uart::COMPATIBLE, &mmio_descriptor)? + }; #[allow(static_mut_refs)] - PL011_UART.write(device_driver::PL011Uart::new(virt_addr)); + unsafe { + PL011_UART.write(device_driver::PL011Uart::new(virt_addr)) + }; Ok(()) } @@ -91,7 +96,7 @@ unsafe fn instantiate_uart() -> Result<(), &'static str> { /// This must be called only after successful init of the PL011 UART driver. unsafe fn post_init_pl011_uart() -> Result<(), &'static str> { #[allow(static_mut_refs)] - console::register_console(PL011_UART.assume_init_ref()); + console::register_console(unsafe { PL011_UART.assume_init_ref() }); crate::info!("UART0 is live!"); Ok(()) } @@ -100,10 +105,12 @@ unsafe fn post_init_pl011_uart() -> Result<(), &'static str> { unsafe fn instantiate_gpio() -> Result<(), &'static str> { let mmio_descriptor = MMIODescriptor::new(mmio::GPIO_BASE, mmio::GPIO_SIZE); let virt_addr = - memory::mmu::kernel_map_mmio(device_driver::GPIO::COMPATIBLE, &mmio_descriptor)?; + unsafe { memory::mmu::kernel_map_mmio(device_driver::GPIO::COMPATIBLE, &mmio_descriptor)? }; #[allow(static_mut_refs)] - GPIO.write(device_driver::GPIO::new(virt_addr)); + unsafe { + GPIO.write(device_driver::GPIO::new(virt_addr)) + }; Ok(()) } @@ -111,7 +118,7 @@ unsafe fn instantiate_gpio() -> Result<(), &'static str> { /// This must be called only after successful init of the GPIO driver. unsafe fn post_init_gpio() -> Result<(), &'static str> { #[allow(static_mut_refs)] - device_driver::PL011Uart::prepare_gpio(GPIO.assume_init_ref()); + device_driver::PL011Uart::prepare_gpio(unsafe { GPIO.assume_init_ref() }); Ok(()) } @@ -120,13 +127,17 @@ unsafe fn post_init_gpio() -> Result<(), &'static str> { unsafe fn instantiate_interrupt_controller() -> Result<(), &'static str> { let periph_mmio_descriptor = MMIODescriptor::new(mmio::PERIPHERAL_IC_BASE, mmio::PERIPHERAL_IC_SIZE); - let periph_virt_addr = memory::mmu::kernel_map_mmio( - device_driver::InterruptController::COMPATIBLE, - &periph_mmio_descriptor, - )?; + let periph_virt_addr = unsafe { + memory::mmu::kernel_map_mmio( + device_driver::InterruptController::COMPATIBLE, + &periph_mmio_descriptor, + )? + }; #[allow(static_mut_refs)] - INTERRUPT_CONTROLLER.write(device_driver::InterruptController::new(periph_virt_addr)); + unsafe { + INTERRUPT_CONTROLLER.write(device_driver::InterruptController::new(periph_virt_addr)); + } Ok(()) } @@ -135,13 +146,17 @@ unsafe fn instantiate_interrupt_controller() -> Result<(), &'static str> { #[cfg(feature = "rpi4")] unsafe fn instantiate_interrupt_controller() -> Result<(), &'static str> { let gicd_mmio_descriptor = MMIODescriptor::new(mmio::GICD_BASE, mmio::GICD_SIZE); - let gicd_virt_addr = memory::mmu::kernel_map_mmio("GICv2 GICD", &gicd_mmio_descriptor)?; + let gicd_virt_addr = + unsafe { memory::mmu::kernel_map_mmio("GICv2 GICD", &gicd_mmio_descriptor)? }; let gicc_mmio_descriptor = MMIODescriptor::new(mmio::GICC_BASE, mmio::GICC_SIZE); - let gicc_virt_addr = memory::mmu::kernel_map_mmio("GICV2 GICC", &gicc_mmio_descriptor)?; + let gicc_virt_addr = + unsafe { memory::mmu::kernel_map_mmio("GICV2 GICC", &gicc_mmio_descriptor)? }; #[allow(static_mut_refs)] - INTERRUPT_CONTROLLER.write(device_driver::GICv2::new(gicd_virt_addr, gicc_virt_addr)); + unsafe { + INTERRUPT_CONTROLLER.write(device_driver::GICv2::new(gicd_virt_addr, gicc_virt_addr)) + }; Ok(()) } @@ -149,18 +164,22 @@ unsafe fn instantiate_interrupt_controller() -> Result<(), &'static str> { /// This must be called only after successful init of the interrupt controller driver. unsafe fn post_init_interrupt_controller() -> Result<(), &'static str> { #[allow(static_mut_refs)] - generic_exception::asynchronous::register_irq_manager(INTERRUPT_CONTROLLER.assume_init_ref()); + generic_exception::asynchronous::register_irq_manager(unsafe { + INTERRUPT_CONTROLLER.assume_init_ref() + }); Ok(()) } /// Function needs to ensure that driver registration happens only after correct instantiation. unsafe fn driver_uart() -> Result<(), &'static str> { - instantiate_uart()?; + unsafe { instantiate_uart()? }; let uart_descriptor = drivers::DeviceDriverDescriptor::new( #[allow(static_mut_refs)] - PL011_UART.assume_init_ref(), + unsafe { + PL011_UART.assume_init_ref() + }, Some(post_init_pl011_uart), Some(exception::asynchronous::irq_map::PL011_UART), ); @@ -171,11 +190,16 @@ unsafe fn driver_uart() -> Result<(), &'static str> { /// Function needs to ensure that driver registration happens only after correct instantiation. unsafe fn driver_gpio() -> Result<(), &'static str> { - instantiate_gpio()?; + unsafe { instantiate_gpio()? }; - #[allow(static_mut_refs)] - let gpio_descriptor = - drivers::DeviceDriverDescriptor::new(GPIO.assume_init_ref(), Some(post_init_gpio), None); + let gpio_descriptor = drivers::DeviceDriverDescriptor::new( + #[allow(static_mut_refs)] + unsafe { + GPIO.assume_init_ref() + }, + Some(post_init_gpio), + None, + ); drivers::driver_manager().register_driver(gpio_descriptor); Ok(()) @@ -183,11 +207,13 @@ unsafe fn driver_gpio() -> Result<(), &'static str> { /// Function needs to ensure that driver registration happens only after correct instantiation. unsafe fn driver_interrupt_controller() -> Result<(), &'static str> { - instantiate_interrupt_controller()?; + unsafe { instantiate_interrupt_controller()? }; let interrupt_controller_descriptor = drivers::DeviceDriverDescriptor::new( #[allow(static_mut_refs)] - INTERRUPT_CONTROLLER.assume_init_ref(), + unsafe { + INTERRUPT_CONTROLLER.assume_init_ref() + }, Some(post_init_interrupt_controller), None, ); diff --git a/machine/src/platform/raspberrypi/memory/mmu.rs b/machine/src/platform/raspberrypi/memory/mmu.rs index ed44c78f..a55c368e 100644 --- a/machine/src/platform/raspberrypi/memory/mmu.rs +++ b/machine/src/platform/raspberrypi/memory/mmu.rs @@ -180,16 +180,18 @@ pub fn virt_mmio_remap_region() -> MemoryRegion { /// /// - Any miscalculation or attribute error will likely be fatal. Needs careful manual checking. pub unsafe fn kernel_map_binary() -> Result<(), &'static str> { - generic_mmu::kernel_map_at( - "Kernel boot-core stack", - &virt_boot_core_stack_region(), - &kernel_virt_to_phys_region(virt_boot_core_stack_region()), - &AttributeFields { - mem_attributes: MemAttributes::CacheableDRAM, - acc_perms: AccessPermissions::ReadWrite, - execute_never: true, - }, - )?; + unsafe { + generic_mmu::kernel_map_at( + "Kernel boot-core stack", + &virt_boot_core_stack_region(), + &kernel_virt_to_phys_region(virt_boot_core_stack_region()), + &AttributeFields { + mem_attributes: MemAttributes::CacheableDRAM, + acc_perms: AccessPermissions::ReadWrite, + execute_never: true, + }, + )? + }; // TranslationDescriptor { // name: "Boot code and data", @@ -213,27 +215,31 @@ pub unsafe fn kernel_map_binary() -> Result<(), &'static str> { // }, // }, - generic_mmu::kernel_map_at( - "Kernel code and RO data", - &virt_code_region(), - &kernel_virt_to_phys_region(virt_code_region()), - &AttributeFields { - mem_attributes: MemAttributes::CacheableDRAM, - acc_perms: AccessPermissions::ReadOnly, - execute_never: false, - }, - )?; - - generic_mmu::kernel_map_at( - "Kernel data and bss", - &virt_data_region(), - &kernel_virt_to_phys_region(virt_data_region()), - &AttributeFields { - mem_attributes: MemAttributes::CacheableDRAM, - acc_perms: AccessPermissions::ReadWrite, - execute_never: true, - }, - )?; + unsafe { + generic_mmu::kernel_map_at( + "Kernel code and RO data", + &virt_code_region(), + &kernel_virt_to_phys_region(virt_code_region()), + &AttributeFields { + mem_attributes: MemAttributes::CacheableDRAM, + acc_perms: AccessPermissions::ReadOnly, + execute_never: false, + }, + )? + }; + + unsafe { + generic_mmu::kernel_map_at( + "Kernel data and bss", + &virt_data_region(), + &kernel_virt_to_phys_region(virt_data_region()), + &AttributeFields { + mem_attributes: MemAttributes::CacheableDRAM, + acc_perms: AccessPermissions::ReadWrite, + execute_never: true, + }, + )? + }; Ok(()) } @@ -287,15 +293,15 @@ mod tests { /// Check if KERNEL_TABLES is in .bss. #[test_case] fn kernel_tables_in_bss() { - extern "Rust" { + unsafe extern "Rust" { static __BSS_START: UnsafeCell; static __BSS_END: UnsafeCell; } let bss_range = unsafe { Range { - start: __BSS_START.get(), - end: __BSS_END.get(), + start: unsafe { __BSS_START.get() }, + end: unsafe { __BSS_END.get() }, } }; let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64; diff --git a/machine/src/platform/raspberrypi/memory/mod.rs b/machine/src/platform/raspberrypi/memory/mod.rs index 8339ed2e..7a248098 100644 --- a/machine/src/platform/raspberrypi/memory/mod.rs +++ b/machine/src/platform/raspberrypi/memory/mod.rs @@ -68,7 +68,7 @@ use { }; // Symbols from the linker script. -extern "Rust" { +unsafe extern "Rust" { // Boot code. // // Using the linker script, we ensure that the boot area is consecutive and 4 diff --git a/nucleus/Cargo.toml b/nucleus/Cargo.toml index f59b55a2..56c74cd6 100644 --- a/nucleus/Cargo.toml +++ b/nucleus/Cargo.toml @@ -1,3 +1,5 @@ +cargo-features = ["edition2024"] + [package] name = "nucleus" description = "Vesper nanokernel binary" diff --git a/nucleus/src/main.rs b/nucleus/src/main.rs index 118ba3a1..2c6fec2b 100644 --- a/nucleus/src/main.rs +++ b/nucleus/src/main.rs @@ -58,23 +58,23 @@ pub unsafe fn kernel_init() -> ! { exception::handling_init(); - let phys_kernel_tables_base_addr = match memory::mmu::kernel_map_binary() { + let phys_kernel_tables_base_addr = match unsafe { memory::mmu::kernel_map_binary() } { Err(string) => panic!("Error mapping kernel binary: {}", string), Ok(addr) => addr, }; - if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) { + if let Err(e) = unsafe { memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) } { panic!("Enabling MMU failed: {}", e); } memory::mmu::post_enable_init(); - 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() }; // Unmask interrupts on the boot CPU core. machine::exception::asynchronous::local_irq_unmask();