From 27a1d10cc3975a8414855c95ac8605588800a7d3 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Mon, 5 Oct 2020 23:47:18 +0200 Subject: [PATCH] Remove UB in linker script symbol <-> Rust handover --- 02_runtime_init/README.md | 42 +++---- 02_runtime_init/src/bsp/raspberrypi/link.ld | 2 +- 02_runtime_init/src/bsp/raspberrypi/memory.rs | 19 ++- 02_runtime_init/src/memory.rs | 15 ++- 02_runtime_init/src/runtime_init.rs | 2 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 03_hacky_hello_world/src/memory.rs | 15 ++- 03_hacky_hello_world/src/runtime_init.rs | 2 +- 04_zero_overhead_abstraction/README.md | 2 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 04_zero_overhead_abstraction/src/memory.rs | 15 ++- .../src/runtime_init.rs | 2 +- 05_safe_globals/src/bsp/raspberrypi/link.ld | 2 +- 05_safe_globals/src/bsp/raspberrypi/memory.rs | 19 ++- 05_safe_globals/src/memory.rs | 15 ++- 05_safe_globals/src/runtime_init.rs | 2 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 06_drivers_gpio_uart/src/memory.rs | 15 ++- 06_drivers_gpio_uart/src/runtime_init.rs | 2 +- 07_uart_chainloader/README.md | 4 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 07_uart_chainloader/src/memory.rs | 15 ++- 07_uart_chainloader/src/runtime_init.rs | 2 +- 08_timestamps/README.md | 4 +- 08_timestamps/src/bsp/raspberrypi/link.ld | 2 +- 08_timestamps/src/bsp/raspberrypi/memory.rs | 19 ++- 08_timestamps/src/memory.rs | 15 ++- 08_timestamps/src/runtime_init.rs | 2 +- 09_hw_debug_JTAG/src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 09_hw_debug_JTAG/src/memory.rs | 15 ++- 09_hw_debug_JTAG/src/runtime_init.rs | 2 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 19 ++- 10_privilege_level/src/memory.rs | 15 ++- 10_privilege_level/src/runtime_init.rs | 2 +- .../README.md | 38 +++--- .../src/_arch/aarch64/memory/mmu.rs | 10 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 27 ++--- .../src/memory.rs | 15 ++- .../src/runtime_init.rs | 2 +- 12_exceptions_part1_groundwork/README.md | 11 +- .../src/_arch/aarch64/exception.rs | 9 +- .../src/_arch/aarch64/memory/mmu.rs | 10 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 27 ++--- 12_exceptions_part1_groundwork/src/memory.rs | 15 ++- .../src/runtime_init.rs | 2 +- 13_integrated_testing/README.md | 114 ++++++++++++------ .../src/_arch/aarch64/exception.rs | 9 +- .../src/_arch/aarch64/memory/mmu.rs | 47 +++++++- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 27 ++--- 13_integrated_testing/src/memory.rs | 33 ++++- 13_integrated_testing/src/runtime_init.rs | 25 +--- 14_exceptions_part2_peripheral_IRQs/README.md | 2 +- .../src/_arch/aarch64/exception.rs | 9 +- .../src/_arch/aarch64/memory/mmu.rs | 47 +++++++- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 27 ++--- .../src/memory.rs | 33 ++++- .../src/runtime_init.rs | 25 +--- 15_virtual_mem_part2_mmio_remap/README.md | 105 ++++++---------- .../src/_arch/aarch64/exception.rs | 9 +- .../src/_arch/aarch64/memory/mmu.rs | 2 +- .../src/bsp/raspberrypi/link.ld | 2 +- .../src/bsp/raspberrypi/memory.rs | 31 ++--- 15_virtual_mem_part2_mmio_remap/src/memory.rs | 33 ++++- .../src/runtime_init.rs | 25 +--- X1_JTAG_boot/jtag_boot_rpi3.img | Bin 7272 -> 7376 bytes X1_JTAG_boot/jtag_boot_rpi4.img | Bin 7240 -> 7360 bytes X1_JTAG_boot/src/bsp/raspberrypi/link.ld | 2 +- X1_JTAG_boot/src/bsp/raspberrypi/memory.rs | 19 ++- X1_JTAG_boot/src/memory.rs | 15 ++- X1_JTAG_boot/src/runtime_init.rs | 2 +- 80 files changed, 637 insertions(+), 574 deletions(-) diff --git a/02_runtime_init/README.md b/02_runtime_init/README.md index 37a76e4e..2b098e4e 100644 --- a/02_runtime_init/README.md +++ b/02_runtime_init/README.md @@ -68,7 +68,7 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/ra + __bss_start = .; + *(.bss*); + . = ALIGN(8); -+ __bss_end = .; ++ __bss_end_inclusive = . - 8; + } + /DISCARD/ : { *(.comment*) } @@ -77,42 +77,37 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/ra diff -uNr 01_wait_forever/src/bsp/raspberrypi/memory.rs 02_runtime_init/src/bsp/raspberrypi/memory.rs --- 01_wait_forever/src/bsp/raspberrypi/memory.rs +++ 02_runtime_init/src/bsp/raspberrypi/memory.rs -@@ -0,0 +1,36 @@ +@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter + +//! BSP Memory Management. + -+use core::ops::Range; ++use core::{cell::UnsafeCell, ops::RangeInclusive}; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. -+extern "C" { -+ static __bss_start: usize; -+ static __bss_end: usize; ++extern "Rust" { ++ static __bss_start: UnsafeCell; ++ static __bss_end_inclusive: UnsafeCell; +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + -+/// Return the range spanning the .bss section. ++/// Return the inclusive range spanning the .bss section. +/// +/// # Safety +/// +/// - Values are provided by the linker script and must be trusted as-is. +/// - The linker-provided addresses must be u64 aligned. -+pub fn bss_range() -> Range<*mut u64> { -+ unsafe { -+ Range { -+ start: &__bss_start as *const _ as *mut u64, -+ end: &__bss_end as *const _ as *mut u64, -+ } -+ } ++pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { ++ unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } +} diff -uNr 01_wait_forever/src/bsp/raspberrypi.rs 02_runtime_init/src/bsp/raspberrypi.rs @@ -155,34 +150,39 @@ diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs diff -uNr 01_wait_forever/src/memory.rs 02_runtime_init/src/memory.rs --- 01_wait_forever/src/memory.rs +++ 02_runtime_init/src/memory.rs -@@ -0,0 +1,29 @@ +@@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter + +//! Memory Management. + -+use core::ops::Range; ++use core::ops::RangeInclusive; + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + -+/// Zero out a memory range. ++/// Zero out an inclusive memory range. +/// +/// # Safety +/// +/// - `range.start` and `range.end` must be valid. +/// - `range.start` and `range.end` must be `T` aligned. -+pub unsafe fn zero_volatile(range: Range<*mut T>) ++pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) +where + T: From, +{ -+ let mut ptr = range.start; ++ let mut ptr = *range.start(); ++ let end_inclusive = *range.end(); + -+ while ptr < range.end { ++ loop { + core::ptr::write_volatile(ptr, T::from(0)); + ptr = ptr.offset(1); ++ ++ if ptr > end_inclusive { ++ break; ++ } + } +} @@ -209,7 +209,7 @@ diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.r +/// - Must only be called pre `kernel_init()`. +#[inline(always)] +unsafe fn zero_bss() { -+ memory::zero_volatile(bsp::memory::bss_range()); ++ memory::zero_volatile(bsp::memory::bss_range_inclusive()); +} + +//-------------------------------------------------------------------------------------------------- diff --git a/02_runtime_init/src/bsp/raspberrypi/link.ld b/02_runtime_init/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/02_runtime_init/src/bsp/raspberrypi/link.ld +++ b/02_runtime_init/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/02_runtime_init/src/bsp/raspberrypi/memory.rs b/02_runtime_init/src/bsp/raspberrypi/memory.rs index ea2ab84c..1cac6d21 100644 --- a/02_runtime_init/src/bsp/raspberrypi/memory.rs +++ b/02_runtime_init/src/bsp/raspberrypi/memory.rs @@ -4,33 +4,28 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/02_runtime_init/src/memory.rs b/02_runtime_init/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/02_runtime_init/src/memory.rs +++ b/02_runtime_init/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/02_runtime_init/src/runtime_init.rs b/02_runtime_init/src/runtime_init.rs index 90ef43c6..3e62cf08 100644 --- a/02_runtime_init/src/runtime_init.rs +++ b/02_runtime_init/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/03_hacky_hello_world/src/bsp/raspberrypi/link.ld b/03_hacky_hello_world/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/03_hacky_hello_world/src/bsp/raspberrypi/link.ld +++ b/03_hacky_hello_world/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs b/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs index ea2ab84c..1cac6d21 100644 --- a/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs +++ b/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs @@ -4,33 +4,28 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/03_hacky_hello_world/src/memory.rs b/03_hacky_hello_world/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/03_hacky_hello_world/src/memory.rs +++ b/03_hacky_hello_world/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/03_hacky_hello_world/src/runtime_init.rs b/03_hacky_hello_world/src/runtime_init.rs index 90ef43c6..3e62cf08 100644 --- a/03_hacky_hello_world/src/runtime_init.rs +++ b/03_hacky_hello_world/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/04_zero_overhead_abstraction/README.md b/04_zero_overhead_abstraction/README.md index a20e0576..804cdf10 100644 --- a/04_zero_overhead_abstraction/README.md +++ b/04_zero_overhead_abstraction/README.md @@ -180,7 +180,7 @@ diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs 04_zero_overhead_ab + map::BOOT_CORE_STACK_END +} + - /// Return the range spanning the .bss section. + /// Return the inclusive range spanning the .bss section. /// /// # Safety diff --git a/04_zero_overhead_abstraction/src/bsp/raspberrypi/link.ld b/04_zero_overhead_abstraction/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/04_zero_overhead_abstraction/src/bsp/raspberrypi/link.ld +++ b/04_zero_overhead_abstraction/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs index cdd5ac99..9e1a819d 100644 --- a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs +++ b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -36,17 +36,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/04_zero_overhead_abstraction/src/memory.rs b/04_zero_overhead_abstraction/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/04_zero_overhead_abstraction/src/memory.rs +++ b/04_zero_overhead_abstraction/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/04_zero_overhead_abstraction/src/runtime_init.rs b/04_zero_overhead_abstraction/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/04_zero_overhead_abstraction/src/runtime_init.rs +++ b/04_zero_overhead_abstraction/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/05_safe_globals/src/bsp/raspberrypi/link.ld b/05_safe_globals/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/05_safe_globals/src/bsp/raspberrypi/link.ld +++ b/05_safe_globals/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/05_safe_globals/src/bsp/raspberrypi/memory.rs b/05_safe_globals/src/bsp/raspberrypi/memory.rs index cdd5ac99..9e1a819d 100644 --- a/05_safe_globals/src/bsp/raspberrypi/memory.rs +++ b/05_safe_globals/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -36,17 +36,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/05_safe_globals/src/memory.rs b/05_safe_globals/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/05_safe_globals/src/memory.rs +++ b/05_safe_globals/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/05_safe_globals/src/runtime_init.rs b/05_safe_globals/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/05_safe_globals/src/runtime_init.rs +++ b/05_safe_globals/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld b/06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld +++ b/06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs index 0b859498..e23fc1d6 100644 --- a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs +++ b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -59,17 +59,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/06_drivers_gpio_uart/src/memory.rs b/06_drivers_gpio_uart/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/06_drivers_gpio_uart/src/memory.rs +++ b/06_drivers_gpio_uart/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/06_drivers_gpio_uart/src/runtime_init.rs b/06_drivers_gpio_uart/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/06_drivers_gpio_uart/src/runtime_init.rs +++ b/06_drivers_gpio_uart/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/07_uart_chainloader/README.md b/07_uart_chainloader/README.md index bbcc4bcb..c87ea43c 100644 --- a/07_uart_chainloader/README.md +++ b/07_uart_chainloader/README.md @@ -263,7 +263,7 @@ diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld 07_uart_chainloader/s { *(.text._start) *(.text*) @@ -32,5 +33,14 @@ - __bss_end = .; + __bss_end_inclusive = . - 8; } + .got : @@ -307,7 +307,7 @@ diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs 07_uart_chainloader + map::BOARD_DEFAULT_LOAD_ADDRESS +} + - /// Return the range spanning the .bss section. + /// Return the inclusive range spanning the .bss section. /// /// # Safety diff --git a/07_uart_chainloader/src/bsp/raspberrypi/link.ld b/07_uart_chainloader/src/bsp/raspberrypi/link.ld index 060faa7b..0aea1212 100644 --- a/07_uart_chainloader/src/bsp/raspberrypi/link.ld +++ b/07_uart_chainloader/src/bsp/raspberrypi/link.ld @@ -30,7 +30,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } .got : diff --git a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs index f871def3..de38dc01 100644 --- a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs +++ b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -67,17 +67,12 @@ pub fn board_default_load_addr() -> usize { map::BOARD_DEFAULT_LOAD_ADDRESS } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/07_uart_chainloader/src/memory.rs b/07_uart_chainloader/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/07_uart_chainloader/src/memory.rs +++ b/07_uart_chainloader/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/07_uart_chainloader/src/runtime_init.rs b/07_uart_chainloader/src/runtime_init.rs index c98c9172..b984f986 100644 --- a/07_uart_chainloader/src/runtime_init.rs +++ b/07_uart_chainloader/src/runtime_init.rs @@ -51,7 +51,7 @@ impl RunTimeInit for Traitor {} /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/08_timestamps/README.md b/08_timestamps/README.md index 77426301..d4af4f66 100644 --- a/08_timestamps/README.md +++ b/08_timestamps/README.md @@ -263,7 +263,7 @@ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/link.ld 08_timestamps/src/bsp/ { *(.text._start) *(.text*) @@ -33,14 +32,5 @@ - __bss_end = .; + __bss_end_inclusive = . - 8; } - .got : @@ -307,7 +307,7 @@ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/memory.rs 08_timestamps/src/bs - map::BOARD_DEFAULT_LOAD_ADDRESS -} - - /// Return the range spanning the .bss section. + /// Return the inclusive range spanning the .bss section. /// /// # Safety diff --git a/08_timestamps/src/bsp/raspberrypi/link.ld b/08_timestamps/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/08_timestamps/src/bsp/raspberrypi/link.ld +++ b/08_timestamps/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/08_timestamps/src/bsp/raspberrypi/memory.rs b/08_timestamps/src/bsp/raspberrypi/memory.rs index 0b859498..e23fc1d6 100644 --- a/08_timestamps/src/bsp/raspberrypi/memory.rs +++ b/08_timestamps/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -59,17 +59,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/08_timestamps/src/memory.rs b/08_timestamps/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/08_timestamps/src/memory.rs +++ b/08_timestamps/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/08_timestamps/src/runtime_init.rs b/08_timestamps/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/08_timestamps/src/runtime_init.rs +++ b/08_timestamps/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/09_hw_debug_JTAG/src/bsp/raspberrypi/link.ld b/09_hw_debug_JTAG/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/09_hw_debug_JTAG/src/bsp/raspberrypi/link.ld +++ b/09_hw_debug_JTAG/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs index 0b859498..e23fc1d6 100644 --- a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs +++ b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -59,17 +59,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/09_hw_debug_JTAG/src/memory.rs b/09_hw_debug_JTAG/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/09_hw_debug_JTAG/src/memory.rs +++ b/09_hw_debug_JTAG/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/09_hw_debug_JTAG/src/runtime_init.rs b/09_hw_debug_JTAG/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/09_hw_debug_JTAG/src/runtime_init.rs +++ b/09_hw_debug_JTAG/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/10_privilege_level/src/bsp/raspberrypi/link.ld b/10_privilege_level/src/bsp/raspberrypi/link.ld index 77420992..6354a501 100644 --- a/10_privilege_level/src/bsp/raspberrypi/link.ld +++ b/10_privilege_level/src/bsp/raspberrypi/link.ld @@ -29,7 +29,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/10_privilege_level/src/bsp/raspberrypi/memory.rs b/10_privilege_level/src/bsp/raspberrypi/memory.rs index 0b859498..e23fc1d6 100644 --- a/10_privilege_level/src/bsp/raspberrypi/memory.rs +++ b/10_privilege_level/src/bsp/raspberrypi/memory.rs @@ -4,16 +4,16 @@ //! BSP Memory Management. -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -59,17 +59,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/10_privilege_level/src/memory.rs b/10_privilege_level/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/10_privilege_level/src/memory.rs +++ b/10_privilege_level/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/10_privilege_level/src/runtime_init.rs b/10_privilege_level/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/10_privilege_level/src/runtime_init.rs +++ b/10_privilege_level/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/11_virtual_mem_part1_identity_mapping/README.md b/11_virtual_mem_part1_identity_mapping/README.md index 1355be4f..adaa466f 100644 --- a/11_virtual_mem_part1_identity_mapping/README.md +++ b/11_virtual_mem_part1_identity_mapping/README.md @@ -152,8 +152,8 @@ type ArchTranslationTable = FixedSizeTranslationTable; /// /// # Safety /// -/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. -static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". +static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); ``` They are populated using `bsp::memory::mmu::virt_mem_layout().virt_addr_properties()` and a bunch of @@ -443,7 +443,7 @@ diff -uNr 10_privilege_level/src/_arch/aarch64/memory/mmu.rs 11_virtual_mem_part +/// # Safety +/// +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". -+static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); ++static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); + +static MMU: MemoryManagementUnit = MemoryManagementUnit; + @@ -559,10 +559,10 @@ diff -uNr 10_privilege_level/src/_arch/aarch64/memory/mmu.rs 11_virtual_mem_part +/// +/// - Modifies a `static mut`. Ensure it only happens from here. +unsafe fn populate_tt_entries() -> Result<(), &'static str> { -+ for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { -+ *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); ++ for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { ++ *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); + -+ for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { ++ for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { + let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); + + let (output_addr, attribute_fields) = @@ -618,7 +618,7 @@ diff -uNr 10_privilege_level/src/_arch/aarch64/memory/mmu.rs 11_virtual_mem_part + populate_tt_entries()?; + + // Set the "Translation Table Base Register". -+ TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); ++ TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); + + configure_translation_control(); + @@ -760,18 +760,18 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_mem_part1_ +pub mod mmu; + - use core::ops::Range; + use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- -@@ -12,6 +14,8 @@ - - // Symbols from the linker script. - extern "C" { -+ static __ro_start: usize; -+ static __ro_end: usize; - static __bss_start: usize; - static __bss_end: usize; +@@ -14,6 +16,8 @@ + extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; ++ static __ro_start: UnsafeCell<()>; ++ static __ro_end: UnsafeCell<()>; } + + //-------------------------------------------------------------------------------------------------- @@ -23,6 +27,8 @@ /// The board's memory map. #[rustfmt::skip] @@ -808,7 +808,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_mem_part1_ +/// - Value is provided by the linker script and must be trusted as-is. +#[inline(always)] +fn ro_start() -> usize { -+ unsafe { &__ro_start as *const _ as usize } ++ unsafe { __ro_start.get() as usize } +} + +/// Size of the Read-Only (RO) range of the kernel binary. @@ -818,7 +818,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_mem_part1_ +/// - Value is provided by the linker script and must be trusted as-is. +#[inline(always)] +fn ro_end() -> usize { -+ unsafe { &__ro_end as *const _ as usize } ++ unsafe { __ro_end.get() as usize } +} + +//-------------------------------------------------------------------------------------------------- @@ -1123,7 +1123,7 @@ diff -uNr 10_privilege_level/src/memory.rs 11_virtual_mem_part1_identity_mapping +pub mod mmu; + - use core::ops::Range; + use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- diff --git a/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/memory/mmu.rs b/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/memory/mmu.rs index 26b755e2..80b03e8a 100644 --- a/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/memory/mmu.rs +++ b/11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/memory/mmu.rs @@ -138,7 +138,7 @@ struct MemoryManagementUnit; /// # Safety /// /// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". -static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -254,10 +254,10 @@ fn set_up_mair() { /// /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_tt_entries() -> Result<(), &'static str> { - for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); + for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { + *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); - for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let (output_addr, attribute_fields) = @@ -313,7 +313,7 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { populate_tt_entries()?; // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); configure_translation_control(); diff --git a/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/link.ld b/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/link.ld index fac86cda..2a1e27a6 100644 --- a/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/link.ld +++ b/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/link.ld @@ -32,7 +32,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/memory.rs b/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/memory.rs index 9d4d3065..1eb2300d 100644 --- a/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/memory.rs +++ b/11_virtual_mem_part1_identity_mapping/src/bsp/raspberrypi/memory.rs @@ -6,18 +6,18 @@ pub mod mmu; -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __ro_start: usize; - static __ro_end: usize; - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; + static __ro_end: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ pub(super) mod map { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_start() -> usize { - unsafe { &__ro_start as *const _ as usize } + unsafe { __ro_start.get() as usize } } /// Size of the Read-Only (RO) range of the kernel binary. @@ -78,7 +78,7 @@ fn ro_start() -> usize { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_end() -> usize { - unsafe { &__ro_end as *const _ as usize } + unsafe { __ro_end.get() as usize } } //-------------------------------------------------------------------------------------------------- @@ -91,17 +91,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/11_virtual_mem_part1_identity_mapping/src/memory.rs b/11_virtual_mem_part1_identity_mapping/src/memory.rs index 40969f94..64c81f25 100644 --- a/11_virtual_mem_part1_identity_mapping/src/memory.rs +++ b/11_virtual_mem_part1_identity_mapping/src/memory.rs @@ -6,26 +6,31 @@ pub mod mmu; -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/11_virtual_mem_part1_identity_mapping/src/runtime_init.rs b/11_virtual_mem_part1_identity_mapping/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/11_virtual_mem_part1_identity_mapping/src/runtime_init.rs +++ b/11_virtual_mem_part1_identity_mapping/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/12_exceptions_part1_groundwork/README.md b/12_exceptions_part1_groundwork/README.md index 64d851a1..7b9c15c4 100644 --- a/12_exceptions_part1_groundwork/README.md +++ b/12_exceptions_part1_groundwork/README.md @@ -486,7 +486,7 @@ diff -uNr 11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/exception.rs 1 //! Architectural synchronous and asynchronous exception handling. -use cortex_a::regs::*; -+use core::fmt; ++use core::{cell::UnsafeCell, fmt}; +use cortex_a::{asm, barrier, regs::*}; +use register::InMemoryRegister; + @@ -713,7 +713,7 @@ diff -uNr 11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/exception.rs 1 //-------------------------------------------------------------------------------------------------- // Public Code -@@ -21,3 +244,24 @@ +@@ -21,3 +244,23 @@ _ => (PrivilegeLevel::Unknown, "Unknown"), } } @@ -728,12 +728,11 @@ diff -uNr 11_virtual_mem_part1_identity_mapping/src/_arch/aarch64/exception.rs 1 +/// Manual. +pub unsafe fn handling_init() { + // Provided by exception.S. -+ extern "C" { -+ static mut __exception_vector_start: u64; ++ extern "Rust" { ++ static __exception_vector_start: UnsafeCell<()>; + } -+ let addr: u64 = &__exception_vector_start as *const _ as u64; + -+ VBAR_EL1.set(addr); ++ VBAR_EL1.set(__exception_vector_start.get() as u64); + + // Force VBAR update to complete before next instruction. + barrier::isb(barrier::SY); diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs index 6c3a75ea..91287bf6 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs @@ -4,7 +4,7 @@ //! Architectural synchronous and asynchronous exception handling. -use core::fmt; +use core::{cell::UnsafeCell, fmt}; use cortex_a::{asm, barrier, regs::*}; use register::InMemoryRegister; @@ -255,12 +255,11 @@ pub fn current_privilege_level() -> (PrivilegeLevel, &'static str) { /// Manual. pub unsafe fn handling_init() { // Provided by exception.S. - extern "C" { - static mut __exception_vector_start: u64; + extern "Rust" { + static __exception_vector_start: UnsafeCell<()>; } - let addr: u64 = &__exception_vector_start as *const _ as u64; - VBAR_EL1.set(addr); + VBAR_EL1.set(__exception_vector_start.get() as u64); // Force VBAR update to complete before next instruction. barrier::isb(barrier::SY); diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs index 26b755e2..80b03e8a 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs @@ -138,7 +138,7 @@ struct MemoryManagementUnit; /// # Safety /// /// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". -static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -254,10 +254,10 @@ fn set_up_mair() { /// /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_tt_entries() -> Result<(), &'static str> { - for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); + for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { + *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); - for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let (output_addr, attribute_fields) = @@ -313,7 +313,7 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { populate_tt_entries()?; // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); configure_translation_control(); diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/link.ld b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/link.ld index 8923b960..5c923a77 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/link.ld +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/link.ld @@ -37,7 +37,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs index 9d4d3065..1eb2300d 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs @@ -6,18 +6,18 @@ pub mod mmu; -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __ro_start: usize; - static __ro_end: usize; - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; + static __ro_end: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ pub(super) mod map { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_start() -> usize { - unsafe { &__ro_start as *const _ as usize } + unsafe { __ro_start.get() as usize } } /// Size of the Read-Only (RO) range of the kernel binary. @@ -78,7 +78,7 @@ fn ro_start() -> usize { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_end() -> usize { - unsafe { &__ro_end as *const _ as usize } + unsafe { __ro_end.get() as usize } } //-------------------------------------------------------------------------------------------------- @@ -91,17 +91,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/12_exceptions_part1_groundwork/src/memory.rs b/12_exceptions_part1_groundwork/src/memory.rs index 40969f94..64c81f25 100644 --- a/12_exceptions_part1_groundwork/src/memory.rs +++ b/12_exceptions_part1_groundwork/src/memory.rs @@ -6,26 +6,31 @@ pub mod mmu; -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/12_exceptions_part1_groundwork/src/runtime_init.rs b/12_exceptions_part1_groundwork/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/12_exceptions_part1_groundwork/src/runtime_init.rs +++ b/12_exceptions_part1_groundwork/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- diff --git a/13_integrated_testing/README.md b/13_integrated_testing/README.md index bb2942bd..5811a488 100644 --- a/13_integrated_testing/README.md +++ b/13_integrated_testing/README.md @@ -720,14 +720,17 @@ RUSTFLAGS="-C link-arg=-Tsrc/bsp/raspberrypi/link.ld -C target-cpu=cortex-a53 -D Finished release [optimized] target(s) in 0.01s Running target/aarch64-unknown-none-softfloat/release/deps/libkernel-4cc6412ddf631982 ------------------------------------------------------------------- - 🦀 Running 5 tests + 🦀 Running 8 tests ------------------------------------------------------------------- - 1. bss_section_is_sane.......................................[ok] - 2. virt_mem_layout_sections_are_64KiB_aligned................[ok] - 3. virt_mem_layout_has_no_overlaps...........................[ok] - 4. test_runner_executes_in_kernel_mode.......................[ok] - 5. zero_volatile_works.......................................[ok] + 1. virt_mem_layout_sections_are_64KiB_aligned................[ok] + 2. virt_mem_layout_has_no_overlaps...........................[ok] + 3. test_runner_executes_in_kernel_mode.......................[ok] + 4. size_of_tabledescriptor_equals_64_bit.....................[ok] + 5. size_of_pagedescriptor_equals_64_bit......................[ok] + 6. kernel_tables_in_bss......................................[ok] + 7. zero_volatile_works.......................................[ok] + 8. bss_section_is_sane.......................................[ok] ------------------------------------------------------------------- ✅ Success: libkernel @@ -974,7 +977,7 @@ diff -uNr 12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs 13_integ @@ -5,7 +5,7 @@ //! Architectural synchronous and asynchronous exception handling. - use core::fmt; + use core::{cell::UnsafeCell, fmt}; -use cortex_a::{asm, barrier, regs::*}; +use cortex_a::{barrier, regs::*}; use register::InMemoryRegister; @@ -998,6 +1001,51 @@ diff -uNr 12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs 13_integ } +diff -uNr 12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs 13_integrated_testing/src/_arch/aarch64/memory/mmu.rs +--- 12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs ++++ 13_integrated_testing/src/_arch/aarch64/memory/mmu.rs +@@ -331,3 +331,40 @@ + Ok(()) + } + } ++ ++//-------------------------------------------------------------------------------------------------- ++// Testing ++//-------------------------------------------------------------------------------------------------- ++ ++#[cfg(test)] ++mod tests { ++ use super::*; ++ use test_macros::kernel_test; ++ ++ /// Check if the size of `struct TableDescriptor` is as expected. ++ #[kernel_test] ++ fn size_of_tabledescriptor_equals_64_bit() { ++ assert_eq!( ++ core::mem::size_of::(), ++ core::mem::size_of::() ++ ); ++ } ++ ++ /// Check if the size of `struct PageDescriptor` is as expected. ++ #[kernel_test] ++ fn size_of_pagedescriptor_equals_64_bit() { ++ assert_eq!( ++ core::mem::size_of::(), ++ core::mem::size_of::() ++ ); ++ } ++ ++ /// Check if KERNEL_TABLES is in .bss. ++ #[kernel_test] ++ fn kernel_tables_in_bss() { ++ let bss_range = bsp::memory::bss_range_inclusive(); ++ let kernel_tables_addr = unsafe { &KERNEL_TABLES as *const _ as usize as *mut u64 }; ++ ++ assert!(bss_range.contains(&kernel_tables_addr)); ++ } ++} + diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/console.rs 13_integrated_testing/src/bsp/raspberrypi/console.rs --- 12_exceptions_part1_groundwork/src/bsp/raspberrypi/console.rs +++ 13_integrated_testing/src/bsp/raspberrypi/console.rs @@ -1478,8 +1526,8 @@ diff -uNr 12_exceptions_part1_groundwork/src/memory/mmu.rs 13_integrated_testing diff -uNr 12_exceptions_part1_groundwork/src/memory.rs 13_integrated_testing/src/memory.rs --- 12_exceptions_part1_groundwork/src/memory.rs +++ 13_integrated_testing/src/memory.rs -@@ -29,3 +29,24 @@ - ptr = ptr.offset(1); +@@ -34,3 +34,40 @@ + } } } + @@ -1497,11 +1545,27 @@ diff -uNr 12_exceptions_part1_groundwork/src/memory.rs 13_integrated_testing/src + fn zero_volatile_works() { + let mut x: [usize; 3] = [10, 11, 12]; + let x_range = x.as_mut_ptr_range(); ++ let x_range_inclusive = ++ RangeInclusive::new(x_range.start, unsafe { x_range.end.offset(-1) }); + -+ unsafe { zero_volatile(x_range) }; ++ unsafe { zero_volatile(x_range_inclusive) }; + + assert_eq!(x, [0, 0, 0]); + } ++ ++ /// Check `bss` section layout. ++ #[kernel_test] ++ fn bss_section_is_sane() { ++ use crate::bsp::memory::bss_range_inclusive; ++ use core::mem; ++ ++ let start = *bss_range_inclusive().start() as usize; ++ let end = *bss_range_inclusive().end() as usize; ++ ++ assert_eq!(start modulo mem::size_of::(), 0); ++ assert_eq!(end modulo mem::size_of::(), 0); ++ assert!(end >= start); ++ } +} diff -uNr 12_exceptions_part1_groundwork/src/panic_wait.rs 13_integrated_testing/src/panic_wait.rs @@ -1553,40 +1617,18 @@ diff -uNr 12_exceptions_part1_groundwork/src/panic_wait.rs 13_integrated_testing diff -uNr 12_exceptions_part1_groundwork/src/runtime_init.rs 13_integrated_testing/src/runtime_init.rs --- 12_exceptions_part1_groundwork/src/runtime_init.rs +++ 13_integrated_testing/src/runtime_init.rs -@@ -31,7 +31,33 @@ +@@ -31,7 +31,10 @@ /// /// - Only a single core must be active and running this function. pub unsafe fn runtime_init() -> ! { +- zero_bss(); + extern "Rust" { + fn kernel_init() -> !; + } -+ - zero_bss(); -+ kernel_init() -+} -+ -+//-------------------------------------------------------------------------------------------------- -+// Testing -+//-------------------------------------------------------------------------------------------------- -+ -+#[cfg(test)] -+mod tests { -+ use super::*; -+ use test_macros::kernel_test; -+ -+ /// Check `bss` section layout. -+ #[kernel_test] -+ fn bss_section_is_sane() { -+ use core::mem; -+ -+ let start = bsp::memory::bss_range().start as *const _ as usize; -+ let end = bsp::memory::bss_range().end as *const _ as usize; - crate::kernel_init() -+ assert_eq!(start modulo mem::size_of::(), 0); -+ assert_eq!(end modulo mem::size_of::(), 0); -+ assert!(end >= start); -+ } ++ zero_bss(); ++ kernel_init() } diff -uNr 12_exceptions_part1_groundwork/test-macros/Cargo.toml 13_integrated_testing/test-macros/Cargo.toml diff --git a/13_integrated_testing/src/_arch/aarch64/exception.rs b/13_integrated_testing/src/_arch/aarch64/exception.rs index 28ea4d41..bbb09b79 100644 --- a/13_integrated_testing/src/_arch/aarch64/exception.rs +++ b/13_integrated_testing/src/_arch/aarch64/exception.rs @@ -4,7 +4,7 @@ //! Architectural synchronous and asynchronous exception handling. -use core::fmt; +use core::{cell::UnsafeCell, fmt}; use cortex_a::{barrier, regs::*}; use register::InMemoryRegister; @@ -245,12 +245,11 @@ pub fn current_privilege_level() -> (PrivilegeLevel, &'static str) { /// Manual. pub unsafe fn handling_init() { // Provided by exception.S. - extern "C" { - static mut __exception_vector_start: u64; + extern "Rust" { + static __exception_vector_start: UnsafeCell<()>; } - let addr: u64 = &__exception_vector_start as *const _ as u64; - VBAR_EL1.set(addr); + VBAR_EL1.set(__exception_vector_start.get() as u64); // Force VBAR update to complete before next instruction. barrier::isb(barrier::SY); diff --git a/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs b/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs index 26b755e2..b9b2f8a0 100644 --- a/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs +++ b/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs @@ -138,7 +138,7 @@ struct MemoryManagementUnit; /// # Safety /// /// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". -static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -254,10 +254,10 @@ fn set_up_mair() { /// /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_tt_entries() -> Result<(), &'static str> { - for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); + for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { + *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); - for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let (output_addr, attribute_fields) = @@ -313,7 +313,7 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { populate_tt_entries()?; // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); configure_translation_control(); @@ -331,3 +331,40 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { Ok(()) } } + +//-------------------------------------------------------------------------------------------------- +// Testing +//-------------------------------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + use test_macros::kernel_test; + + /// Check if the size of `struct TableDescriptor` is as expected. + #[kernel_test] + fn size_of_tabledescriptor_equals_64_bit() { + assert_eq!( + core::mem::size_of::(), + core::mem::size_of::() + ); + } + + /// Check if the size of `struct PageDescriptor` is as expected. + #[kernel_test] + fn size_of_pagedescriptor_equals_64_bit() { + assert_eq!( + core::mem::size_of::(), + core::mem::size_of::() + ); + } + + /// Check if KERNEL_TABLES is in .bss. + #[kernel_test] + fn kernel_tables_in_bss() { + let bss_range = bsp::memory::bss_range_inclusive(); + let kernel_tables_addr = unsafe { &KERNEL_TABLES as *const _ as usize as *mut u64 }; + + assert!(bss_range.contains(&kernel_tables_addr)); + } +} diff --git a/13_integrated_testing/src/bsp/raspberrypi/link.ld b/13_integrated_testing/src/bsp/raspberrypi/link.ld index 8923b960..5c923a77 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/link.ld +++ b/13_integrated_testing/src/bsp/raspberrypi/link.ld @@ -37,7 +37,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/13_integrated_testing/src/bsp/raspberrypi/memory.rs b/13_integrated_testing/src/bsp/raspberrypi/memory.rs index 9d4d3065..1eb2300d 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/memory.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/memory.rs @@ -6,18 +6,18 @@ pub mod mmu; -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __ro_start: usize; - static __ro_end: usize; - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; + static __ro_end: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -68,7 +68,7 @@ pub(super) mod map { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_start() -> usize { - unsafe { &__ro_start as *const _ as usize } + unsafe { __ro_start.get() as usize } } /// Size of the Read-Only (RO) range of the kernel binary. @@ -78,7 +78,7 @@ fn ro_start() -> usize { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_end() -> usize { - unsafe { &__ro_end as *const _ as usize } + unsafe { __ro_end.get() as usize } } //-------------------------------------------------------------------------------------------------- @@ -91,17 +91,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/13_integrated_testing/src/memory.rs b/13_integrated_testing/src/memory.rs index 65d4b92b..76041890 100644 --- a/13_integrated_testing/src/memory.rs +++ b/13_integrated_testing/src/memory.rs @@ -6,27 +6,32 @@ pub mod mmu; -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } @@ -44,9 +49,25 @@ mod tests { fn zero_volatile_works() { let mut x: [usize; 3] = [10, 11, 12]; let x_range = x.as_mut_ptr_range(); + let x_range_inclusive = + RangeInclusive::new(x_range.start, unsafe { x_range.end.offset(-1) }); - unsafe { zero_volatile(x_range) }; + unsafe { zero_volatile(x_range_inclusive) }; assert_eq!(x, [0, 0, 0]); } + + /// Check `bss` section layout. + #[kernel_test] + fn bss_section_is_sane() { + use crate::bsp::memory::bss_range_inclusive; + use core::mem; + + let start = *bss_range_inclusive().start() as usize; + let end = *bss_range_inclusive().end() as usize; + + assert_eq!(start % mem::size_of::(), 0); + assert_eq!(end % mem::size_of::(), 0); + assert!(end >= start); + } } diff --git a/13_integrated_testing/src/runtime_init.rs b/13_integrated_testing/src/runtime_init.rs index a882dbe3..1306578d 100644 --- a/13_integrated_testing/src/runtime_init.rs +++ b/13_integrated_testing/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- @@ -38,26 +38,3 @@ pub unsafe fn runtime_init() -> ! { zero_bss(); kernel_init() } - -//-------------------------------------------------------------------------------------------------- -// Testing -//-------------------------------------------------------------------------------------------------- - -#[cfg(test)] -mod tests { - use super::*; - use test_macros::kernel_test; - - /// Check `bss` section layout. - #[kernel_test] - fn bss_section_is_sane() { - use core::mem; - - let start = bsp::memory::bss_range().start as *const _ as usize; - let end = bsp::memory::bss_range().end as *const _ as usize; - - assert_eq!(start % mem::size_of::(), 0); - assert_eq!(end % mem::size_of::(), 0); - assert!(end >= start); - } -} diff --git a/14_exceptions_part2_peripheral_IRQs/README.md b/14_exceptions_part2_peripheral_IRQs/README.md index 61280808..3e6a4f5b 100644 --- a/14_exceptions_part2_peripheral_IRQs/README.md +++ b/14_exceptions_part2_peripheral_IRQs/README.md @@ -853,7 +853,7 @@ diff -uNr 13_integrated_testing/src/_arch/aarch64/exception.rs 14_exceptions_par //! Architectural synchronous and asynchronous exception handling. +use crate::{bsp, exception}; - use core::fmt; + use core::{cell::UnsafeCell, fmt}; use cortex_a::{barrier, regs::*}; use register::InMemoryRegister; @@ -84,8 +85,11 @@ diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs index c57784a4..047a2195 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs @@ -5,7 +5,7 @@ //! Architectural synchronous and asynchronous exception handling. use crate::{bsp, exception}; -use core::fmt; +use core::{cell::UnsafeCell, fmt}; use cortex_a::{barrier, regs::*}; use register::InMemoryRegister; @@ -249,12 +249,11 @@ pub fn current_privilege_level() -> (PrivilegeLevel, &'static str) { /// Manual. pub unsafe fn handling_init() { // Provided by exception.S. - extern "C" { - static mut __exception_vector_start: u64; + extern "Rust" { + static __exception_vector_start: UnsafeCell<()>; } - let addr: u64 = &__exception_vector_start as *const _ as u64; - VBAR_EL1.set(addr); + VBAR_EL1.set(__exception_vector_start.get() as u64); // Force VBAR update to complete before next instruction. barrier::isb(barrier::SY); diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs index 26b755e2..b9b2f8a0 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs @@ -138,7 +138,7 @@ struct MemoryManagementUnit; /// # Safety /// /// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". -static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -254,10 +254,10 @@ fn set_up_mair() { /// /// - Modifies a `static mut`. Ensure it only happens from here. unsafe fn populate_tt_entries() -> Result<(), &'static str> { - for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { - *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); + for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { + *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); - for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { + for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); let (output_addr, attribute_fields) = @@ -313,7 +313,7 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { populate_tt_entries()?; // Set the "Translation Table Base Register". - TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); + TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); configure_translation_control(); @@ -331,3 +331,40 @@ impl memory::mmu::interface::MMU for MemoryManagementUnit { Ok(()) } } + +//-------------------------------------------------------------------------------------------------- +// Testing +//-------------------------------------------------------------------------------------------------- + +#[cfg(test)] +mod tests { + use super::*; + use test_macros::kernel_test; + + /// Check if the size of `struct TableDescriptor` is as expected. + #[kernel_test] + fn size_of_tabledescriptor_equals_64_bit() { + assert_eq!( + core::mem::size_of::(), + core::mem::size_of::() + ); + } + + /// Check if the size of `struct PageDescriptor` is as expected. + #[kernel_test] + fn size_of_pagedescriptor_equals_64_bit() { + assert_eq!( + core::mem::size_of::(), + core::mem::size_of::() + ); + } + + /// Check if KERNEL_TABLES is in .bss. + #[kernel_test] + fn kernel_tables_in_bss() { + let bss_range = bsp::memory::bss_range_inclusive(); + let kernel_tables_addr = unsafe { &KERNEL_TABLES as *const _ as usize as *mut u64 }; + + assert!(bss_range.contains(&kernel_tables_addr)); + } +} diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/link.ld b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/link.ld index 8923b960..5c923a77 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/link.ld +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/link.ld @@ -37,7 +37,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } /DISCARD/ : { *(.comment*) } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs index 7a4078c7..2cf1a297 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs @@ -6,18 +6,18 @@ pub mod mmu; -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __ro_start: usize; - static __ro_end: usize; - static __bss_start: usize; - static __bss_end: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; + static __ro_end: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -72,7 +72,7 @@ pub(super) mod map { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_start() -> usize { - unsafe { &__ro_start as *const _ as usize } + unsafe { __ro_start.get() as usize } } /// Size of the Read-Only (RO) range of the kernel binary. @@ -82,7 +82,7 @@ fn ro_start() -> usize { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_end() -> usize { - unsafe { &__ro_end as *const _ as usize } + unsafe { __ro_end.get() as usize } } //-------------------------------------------------------------------------------------------------- @@ -95,17 +95,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/memory.rs b/14_exceptions_part2_peripheral_IRQs/src/memory.rs index 65d4b92b..76041890 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/memory.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/memory.rs @@ -6,27 +6,32 @@ pub mod mmu; -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } @@ -44,9 +49,25 @@ mod tests { fn zero_volatile_works() { let mut x: [usize; 3] = [10, 11, 12]; let x_range = x.as_mut_ptr_range(); + let x_range_inclusive = + RangeInclusive::new(x_range.start, unsafe { x_range.end.offset(-1) }); - unsafe { zero_volatile(x_range) }; + unsafe { zero_volatile(x_range_inclusive) }; assert_eq!(x, [0, 0, 0]); } + + /// Check `bss` section layout. + #[kernel_test] + fn bss_section_is_sane() { + use crate::bsp::memory::bss_range_inclusive; + use core::mem; + + let start = *bss_range_inclusive().start() as usize; + let end = *bss_range_inclusive().end() as usize; + + assert_eq!(start % mem::size_of::(), 0); + assert_eq!(end % mem::size_of::(), 0); + assert!(end >= start); + } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs b/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs index a882dbe3..1306578d 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- @@ -38,26 +38,3 @@ pub unsafe fn runtime_init() -> ! { zero_bss(); kernel_init() } - -//-------------------------------------------------------------------------------------------------- -// Testing -//-------------------------------------------------------------------------------------------------- - -#[cfg(test)] -mod tests { - use super::*; - use test_macros::kernel_test; - - /// Check `bss` section layout. - #[kernel_test] - fn bss_section_is_sane() { - use core::mem; - - let start = bsp::memory::bss_range().start as *const _ as usize; - let end = bsp::memory::bss_range().end as *const _ as usize; - - assert_eq!(start % mem::size_of::(), 0); - assert_eq!(end % mem::size_of::(), 0); - assert!(end >= start); - } -} diff --git a/15_virtual_mem_part2_mmio_remap/README.md b/15_virtual_mem_part2_mmio_remap/README.md index 5c341362..f15bc444 100644 --- a/15_virtual_mem_part2_mmio_remap/README.md +++ b/15_virtual_mem_part2_mmio_remap/README.md @@ -452,7 +452,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs 15 /// # Safety /// /// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". --static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); +-static mut KERNEL_TABLES: ArchTranslationTable = ArchTranslationTable::new(); +static KERNEL_TABLES: InitStateLock = + InitStateLock::new(ArchTranslationTable::new()); @@ -591,10 +591,10 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs 15 -/// -/// - Modifies a `static mut`. Ensure it only happens from here. -unsafe fn populate_tt_entries() -> Result<(), &'static str> { -- for (l2_nr, l2_entry) in TABLES.lvl2.iter_mut().enumerate() { -- *l2_entry = TABLES.lvl3[l2_nr].base_addr_usize().into(); +- for (l2_nr, l2_entry) in KERNEL_TABLES.lvl2.iter_mut().enumerate() { +- *l2_entry = KERNEL_TABLES.lvl3[l2_nr].base_addr_usize().into(); - -- for (l3_nr, l3_entry) in TABLES.lvl3[l2_nr].iter_mut().enumerate() { +- for (l3_nr, l3_entry) in KERNEL_TABLES.lvl3[l2_nr].iter_mut().enumerate() { - let virt_addr = (l2_nr << FIVETWELVE_MIB_SHIFT) + (l3_nr << SIXTYFOUR_KIB_SHIFT); - - let (output_addr, attribute_fields) = @@ -678,14 +678,14 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs 15 + if p.len() != v.len() { + return Err("Tried to map page slices with unequal sizes"); + } -+ + +-impl memory::mmu::interface::MMU for MemoryManagementUnit { +- unsafe fn init(&self) -> Result<(), &'static str> { + // No work to do for empty slices. + if p.is_empty() { + return Ok(()); + } - --impl memory::mmu::interface::MMU for MemoryManagementUnit { -- unsafe fn init(&self) -> Result<(), &'static str> { ++ + if p.last().unwrap().as_ptr() >= bsp::memory::mmu::phys_addr_space_end_page() { + return Err("Tried to map outside of physical address space"); + } @@ -757,55 +757,30 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs 15 - populate_tt_entries()?; - // Set the "Translation Table Base Register". -- TTBR0_EL1.set_baddr(TABLES.lvl2.base_addr_u64()); +- TTBR0_EL1.set_baddr(KERNEL_TABLES.lvl2.base_addr_u64()); + TTBR0_EL1.set_baddr(phys_kernel_table_base_addr.into_usize() as u64); configure_translation_control(); -@@ -331,3 +511,43 @@ - Ok(()) - } - } -+ -+//-------------------------------------------------------------------------------------------------- -+// Testing -+//-------------------------------------------------------------------------------------------------- -+ -+#[cfg(test)] +@@ -337,6 +517,9 @@ + //-------------------------------------------------------------------------------------------------- + + #[cfg(test)] +pub(in crate::memory::mmu) type MinSizeArchTranslationTable = FixedSizeTranslationTable<1>; + +#[cfg(test)] -+mod tests { -+ use super::*; -+ use test_macros::kernel_test; -+ -+ /// Check if the size of `struct TableDescriptor` is as expected. -+ #[kernel_test] -+ fn size_of_tabledescriptor_equals_64_bit() { -+ assert_eq!( -+ core::mem::size_of::(), -+ core::mem::size_of::() -+ ); -+ } -+ -+ /// Check if the size of `struct PageDescriptor` is as expected. -+ #[kernel_test] -+ fn size_of_pagedescriptor_equals_64_bit() { -+ assert_eq!( -+ core::mem::size_of::(), -+ core::mem::size_of::() -+ ); -+ } -+ -+ /// Check if KERNEL_TABLES is in .bss. -+ #[kernel_test] -+ fn kernel_tables_in_bss() { -+ let bss_range = bsp::memory::bss_range(); + mod tests { + use super::*; + use test_macros::kernel_test; +@@ -363,7 +546,7 @@ + #[kernel_test] + fn kernel_tables_in_bss() { + let bss_range = bsp::memory::bss_range_inclusive(); +- let kernel_tables_addr = unsafe { &KERNEL_TABLES as *const _ as usize as *mut u64 }; + let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64; -+ -+ assert!(bss_range.contains(&kernel_tables_addr)); -+ } -+} + + assert!(bss_range.contains(&kernel_tables_addr)); + } diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicc.rs 15_virtual_mem_part2_mmio_remap/src/bsp/device_driver/arm/gicv2/gicc.rs --- 14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2/gicc.rs @@ -1467,7 +1442,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/link.ld 15_vir +++ 15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/link.ld @@ -39,6 +39,11 @@ . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } + . = ALIGN(65536); + __data_end = .; @@ -1749,18 +1724,16 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs 15_v pub mod mmu; +use crate::memory::mmu::{Address, Physical, Virtual}; - use core::ops::Range; + use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- -@@ -15,36 +47,41 @@ - // Symbols from the linker script. - extern "C" { - static __ro_start: usize; -- static __ro_end: usize; -+ static __ro_size: usize; - static __bss_start: usize; - static __bss_end: usize; -+ static __data_size: usize; +@@ -17,34 +49,39 @@ + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; +- static __ro_end: UnsafeCell<()>; ++ static __ro_size: UnsafeCell<()>; ++ static __data_size: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -1841,9 +1814,9 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs 15_v /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] -fn ro_start() -> usize { -- unsafe { &__ro_start as *const _ as usize } +- unsafe { __ro_start.get() as usize } +fn virt_ro_start() -> Address { -+ Address::new(unsafe { &__ro_start as *const _ as usize }) ++ Address::new(unsafe { __ro_start.get() as usize }) } /// Size of the Read-Only (RO) range of the kernel binary. @@ -1852,9 +1825,9 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs 15_v /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] -fn ro_end() -> usize { -- unsafe { &__ro_end as *const _ as usize } +- unsafe { __ro_end.get() as usize } +fn ro_size() -> usize { -+ unsafe { &__ro_size as *const _ as usize } ++ unsafe { __ro_size.get() as usize } +} + +/// Start address of the data range. @@ -1870,7 +1843,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs 15_v +/// - Value is provided by the linker script and must be trusted as-is. +#[inline(always)] +fn data_size() -> usize { -+ unsafe { &__data_size as *const _ as usize } ++ unsafe { __data_size.get() as usize } +} + +/// Start address of the boot core's stack. @@ -1904,7 +1877,7 @@ diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs 15_v + Address::new(end) } - /// Return the range spanning the .bss section. + /// Return the inclusive range spanning the .bss section. diff -uNr 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs 15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi.rs --- 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs diff --git a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/exception.rs b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/exception.rs index c57784a4..047a2195 100644 --- a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/exception.rs +++ b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/exception.rs @@ -5,7 +5,7 @@ //! Architectural synchronous and asynchronous exception handling. use crate::{bsp, exception}; -use core::fmt; +use core::{cell::UnsafeCell, fmt}; use cortex_a::{barrier, regs::*}; use register::InMemoryRegister; @@ -249,12 +249,11 @@ pub fn current_privilege_level() -> (PrivilegeLevel, &'static str) { /// Manual. pub unsafe fn handling_init() { // Provided by exception.S. - extern "C" { - static mut __exception_vector_start: u64; + extern "Rust" { + static __exception_vector_start: UnsafeCell<()>; } - let addr: u64 = &__exception_vector_start as *const _ as u64; - VBAR_EL1.set(addr); + VBAR_EL1.set(__exception_vector_start.get() as u64); // Force VBAR update to complete before next instruction. barrier::isb(barrier::SY); diff --git a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/memory/mmu.rs b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/memory/mmu.rs index 0d443e60..b20edf0a 100644 --- a/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/memory/mmu.rs +++ b/15_virtual_mem_part2_mmio_remap/src/_arch/aarch64/memory/mmu.rs @@ -545,7 +545,7 @@ mod tests { /// Check if KERNEL_TABLES is in .bss. #[kernel_test] fn kernel_tables_in_bss() { - let bss_range = bsp::memory::bss_range(); + let bss_range = bsp::memory::bss_range_inclusive(); let kernel_tables_addr = &KERNEL_TABLES as *const _ as usize as *mut u64; assert!(bss_range.contains(&kernel_tables_addr)); diff --git a/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/link.ld b/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/link.ld index 1e97ff1f..c78ef8ef 100644 --- a/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/link.ld +++ b/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/link.ld @@ -37,7 +37,7 @@ SECTIONS __bss_start = .; *(.bss*); . = ALIGN(8); - __bss_end = .; + __bss_end_inclusive = . - 8; } . = ALIGN(65536); __data_end = .; diff --git a/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/memory.rs b/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/memory.rs index 1a9f7312..7376e229 100644 --- a/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/memory.rs +++ b/15_virtual_mem_part2_mmio_remap/src/bsp/raspberrypi/memory.rs @@ -38,19 +38,19 @@ pub mod mmu; use crate::memory::mmu::{Address, Physical, Virtual}; -use core::ops::Range; +use core::{cell::UnsafeCell, ops::RangeInclusive}; //-------------------------------------------------------------------------------------------------- // Private Definitions //-------------------------------------------------------------------------------------------------- // Symbols from the linker script. -extern "C" { - static __ro_start: usize; - static __ro_size: usize; - static __bss_start: usize; - static __bss_end: usize; - static __data_size: usize; +extern "Rust" { + static __bss_start: UnsafeCell; + static __bss_end_inclusive: UnsafeCell; + static __ro_start: UnsafeCell<()>; + static __ro_size: UnsafeCell<()>; + static __data_size: UnsafeCell<()>; } //-------------------------------------------------------------------------------------------------- @@ -118,7 +118,7 @@ pub(super) mod map { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn virt_ro_start() -> Address { - Address::new(unsafe { &__ro_start as *const _ as usize }) + Address::new(unsafe { __ro_start.get() as usize }) } /// Size of the Read-Only (RO) range of the kernel binary. @@ -128,7 +128,7 @@ fn virt_ro_start() -> Address { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn ro_size() -> usize { - unsafe { &__ro_size as *const _ as usize } + unsafe { __ro_size.get() as usize } } /// Start address of the data range. @@ -144,7 +144,7 @@ fn virt_data_start() -> Address { /// - Value is provided by the linker script and must be trusted as-is. #[inline(always)] fn data_size() -> usize { - unsafe { &__data_size as *const _ as usize } + unsafe { __data_size.get() as usize } } /// Start address of the boot core's stack. @@ -177,17 +177,12 @@ pub fn phys_boot_core_stack_end() -> Address { Address::new(end) } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/15_virtual_mem_part2_mmio_remap/src/memory.rs b/15_virtual_mem_part2_mmio_remap/src/memory.rs index 65d4b92b..76041890 100644 --- a/15_virtual_mem_part2_mmio_remap/src/memory.rs +++ b/15_virtual_mem_part2_mmio_remap/src/memory.rs @@ -6,27 +6,32 @@ pub mod mmu; -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } @@ -44,9 +49,25 @@ mod tests { fn zero_volatile_works() { let mut x: [usize; 3] = [10, 11, 12]; let x_range = x.as_mut_ptr_range(); + let x_range_inclusive = + RangeInclusive::new(x_range.start, unsafe { x_range.end.offset(-1) }); - unsafe { zero_volatile(x_range) }; + unsafe { zero_volatile(x_range_inclusive) }; assert_eq!(x, [0, 0, 0]); } + + /// Check `bss` section layout. + #[kernel_test] + fn bss_section_is_sane() { + use crate::bsp::memory::bss_range_inclusive; + use core::mem; + + let start = *bss_range_inclusive().start() as usize; + let end = *bss_range_inclusive().end() as usize; + + assert_eq!(start % mem::size_of::(), 0); + assert_eq!(end % mem::size_of::(), 0); + assert!(end >= start); + } } diff --git a/15_virtual_mem_part2_mmio_remap/src/runtime_init.rs b/15_virtual_mem_part2_mmio_remap/src/runtime_init.rs index a882dbe3..1306578d 100644 --- a/15_virtual_mem_part2_mmio_remap/src/runtime_init.rs +++ b/15_virtual_mem_part2_mmio_remap/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //-------------------------------------------------------------------------------------------------- @@ -38,26 +38,3 @@ pub unsafe fn runtime_init() -> ! { zero_bss(); kernel_init() } - -//-------------------------------------------------------------------------------------------------- -// Testing -//-------------------------------------------------------------------------------------------------- - -#[cfg(test)] -mod tests { - use super::*; - use test_macros::kernel_test; - - /// Check `bss` section layout. - #[kernel_test] - fn bss_section_is_sane() { - use core::mem; - - let start = bsp::memory::bss_range().start as *const _ as usize; - let end = bsp::memory::bss_range().end as *const _ as usize; - - assert_eq!(start % mem::size_of::(), 0); - assert_eq!(end % mem::size_of::(), 0); - assert!(end >= start); - } -} diff --git a/X1_JTAG_boot/jtag_boot_rpi3.img b/X1_JTAG_boot/jtag_boot_rpi3.img index ffb8a905b9c3b9d5aa92b9e54eb09eafa5795ac2..41c4110be90b0a7bff8c9fc6e5c751f2def2c599 100755 GIT binary patch delta 1948 zcmZ8ieN0nV6hHU9eghRsX>AL(2!d_#1DOaekq3UvuZ>uni2n?T*%D=21h!>awzOtj zWJ3*iSEn;e#ON|!byEjM`C}UlmyJ1@h7GsBD7a)m5oJ1Kb?|m>`*6u_!n>Sve)o5N z=YE`ym0d4y%O-UfaukxaTnmQ@!1?Gcpt+DuM@686oy9^n5qh#&wfMXs_}Muzuyxx4 zI)SmMUMF*Wu4e&_t_3<)sF629I51JDm5u24*5^?Cj9nTZxRRj)u!1D`W z9KcV9*|VCBwq7eWqr+hAKb}}PvVsnbnAsW4LZRNxe%5TT)qCi;3*wt+UK||9)SEAw zT_}YWw$03jI>dB+^+Hm0A za6Xnx=vfulBi0TX5X03NDodz0w}iUigNJTnjP)x@@J&TI%F94p{*cl~Zp@ZI{7YQi zg7q8z_^hd22VEwBwuIQ?1#G*nNkF~d>k7z8Hl=ft%gm^Mi@Wyg7lv{R>7*XwN=PG* z`9+y$Hq;l=v5;0C?E~7vRXtLk;*~v7AI+z`+83$n3n<4eds3woZve0w@+BFoibO?2 zWJEMZKm;r2AS4_B&tl4}jEe5ani2ePW3KF0O*mlOxgqY;O5J<1tR+4zboX1r0TcRa zk3hFq3)61g?q1vq(@r*^b?GtU{usJhk)haD?4l`{CKdlC@Ln_!7dP(l2Ia*9{ z2dw;jtE3g3S5r!fK>h4yS`PE1T@?2DJ8!1lAliGP5V_AjpJxxfj_3-Mn`?z&t67Ri zgv{1)EVmU8=(d;@nTPQrn^g8;7FZ_5jL3k|ynPBwHrt#f1H|GRu3XnxmkPmyB<*Sg z^2o&4dRt75v}+((OVVQD6bMd=X^}%&J!Mm~O6dt=iVfs|1qcMsX{Av4StHPCTyO^y z4DS;g`(~7&7L(o)-M(qj6yd%+^i>F^SQH@0#k8qnhI_@vwf`jXcjxfvJM}n;uY9Bg z|3d#DUi(Qbrk13}Ko7wf=6e|hUDJdfmWEK#8CB6CtyF#x1^t8x4!q#p9>V0`V$y6B zG>JsFQ4sfuA_Tv|bv+pSB1VvAjEZ?7Atknn7+d+K;{mf18IJWFxmz$^tssUNm(AH) zFwR$wBO5O{ys%0h!T(3a%*g%fDp^dE;tzII%Coh79d+OydWp>>*i&PBh$+E-2HCe* z9QxK#seCi)Zm>9olYX|}QoebTs>Fsrc72g>fu`jiGE0?mE z^$0UqKTYrPW5*5$_(Q*i^+niM)*_*DX=lv3n)v<~+&ZHiopniZa@wVLd z6|CB}i1^uSwnEl!tFf%HV<*C4OMGz;?aX9fK;B?pdv$TU8pP+A7^hSlsS@L~YO5xk zX0rVfyFPz8ImU>??&z>3$(x&YE!*3)`;}LhHZ^l>IxBWOLwY!dbTI00lNNTtQHTxm zcZWOUH%D?6KHJ3jlNp_>NII)@mKCe6EBYiP`30DpJ5>K=b-to!AIvYU**n~v6FoK zc@mVzq%$AG&Im7xWz5Jq$9XFJ5lcns6VUv4uIi2xCcJuw$ewabm zn@8+^43Vu8yxk&7$^_Q7g!rFSRV~q^IZZwppCPCyA4=eUYRb(;;#~vsR^Ki?1=F_jpsL& zCEAc@%JZgI@rss_d9adBcjvjCTDJGpC$)+_tV*bYwx=ufs;s1%rsrYxHvc655_{(6bEo40Ubi4B=0JAQMG zp*2!RxQb=W>zrYUM#d%Vqi>Y7i707=Hn6ppa?;4QTfQI@Lw77^h+SSoF<7Vei5rft z89H0Aj&Qdl?7Xd%71>6(-y=ikZP$pf$aAT`*pb4L?(N8q39zuY2oil(81Ask*%=Hp z#W{O#@vc;d0Q4r#^Smu(caPOxDFyKpxLb3JFG|hvh0Url-`)AW%UAv3BZLz=K}7L6J}7C<7IgjL6 z{%*tm)~tIt%cZ3=Fkpm*eQ2Yp&EOXZpkixTgEEQlQ@k^^*xaD-HaUA|TfOq2W#U*X z1h4OBZDOo&fLoT?MXWiG$2liEDSAyEQ*zyAjQ)z~;{=Ii#5z`Fch)#`(RbF#qf5eO z6a^Byj`v2*o-GZ^Z6nYT45k%>*&)i=H1A|@6+go{RQ7dokQ=OG&8~y&b?28wA&G|Z zj!X0A)D4XKJPW(35FcuGttZkW;LiK%p$C3BtK!X~osdwdLAx*ygdxg?+!dsW{o<}< z|F~Zfe|6*8#Np2U0xY`Ou9D@%!+J`ZqjE_e#IDbcjrtm;a-&gS>q}^47S9>!u#mUP z{{k${PILZkg+3n^Sif(jzbTO4ZuR8nt@?VO$IQ-p){;fG;3@Go>T&MwYJcMGuAOi0 zS>3f;a~on|@3Y=2$pv=N8+1&2^GxjS-1wViy)`7nqQ2U# z5>&zls0AbB5?&w5Q}+4(FTS+KdmuMz^?dXtwqkxf#iIV0cvZI!>AUkj_JRM7Z{D95 U_3PW)@Q(re1?K(i)4$SO5S3 diff --git a/X1_JTAG_boot/jtag_boot_rpi4.img b/X1_JTAG_boot/jtag_boot_rpi4.img index 81d366b000b6275f95181f48debd2cd1afe62d44..ce930fa10c89a2509676afc82bc31c5d49e39b5c 100755 GIT binary patch delta 1712 zcmZ8hUrbY182`>a{dY@SrT;Bp=?FtwB!k8dG};TOL0nwGyEv02g@-L0xQEVUFU!*M zunbo;Tn}!UTO!6Su@^HTun=ApWyy3p636D_DEcs<2t(9aH|W0G-e$>8(thXr`}=+0 zIp^MLm}(p-C2x(EtrJJB76u8xh;OPyN<9SW0R`#aSS9BsT)dQpX*YM%&xUE6b*)TV zsL~`C&~L=}HeVUjYqq;nWm2jIq!59@awz{5&;?U|>36nQBZi`OX(bHF9sI5H{Klc# z>W}Y!RlRX|cE?3yNv?)uk(LqDf=M$M>!mFySAAagqsGtq%GtUmWXiE3$cjj2wo6+< z?y}?Bs$;{Dhnu32`v%N1kf6k)te&rzyq~~xFX7X-vsv+@Z1xLi7!M#opk*Cc&}C`~ zbi4>+;xaYMXB<-vE1TKS1!7Fklz|lph*z~j;}ssHHB4AVfVo~8o!-cbS_ECCUjG_3 z%8IQ5ZDG!sP9b51%z#Q}?govv{F9IWvk;HAOMmC%n_gta$28{k&t|i(W$Y$GOli=A zm`1?&ke*d0h@DUy*{0gxut>eCA1wxy@%~B z4sVHZMd?F?Pbf3T17?ZhZ3mRd_c;Dem>ALuZKYZt`jyN@tfsUaf2lb+kNXGICO>(- zIZ4ez=Gn2PrT>*B|+Nf1fd)cVf7F2ehhlI%j2Ls{* z3Evk8yvjP7lTURZeUH35k$0a}$fT%^{bfDCJ=tXYY+jDkjzw&{$<}y4^5NGZMGf*p z>`rD$dks2S#CDFIaD4lJ|7*%^&1X!2Ti*NV8#p2F4t+g)vM&WX*_Wdrl ztaUNk-7oZi;pw6n5yGfIkyH?T~%R_opMdE5%(*kkIlPXWRPXt5i+9gquUnh z)W{Ki9yb3EP>_SF{To$|=vlY><>N!8`G8JOUS3x9K2`Ta73_fq&_SN*?(#fNO7$1` y6?D9@xn*aP$3@&M=?PnRl;mrdtG?C}_QLbb)2c$1sODoD0DKwHTFQ*2`~C$=$n^UF delta 1645 zcmZ8hT}%{L6h3$E&hE_0F6?ynhh1=YMTME7#Sjs+?T#p>*eEUCL~S2{hbB~Bine`d zV#GEkSZw3u(%5PfAWc(uOstk|3~6E)snN!UQhy%>>;uY=Qh≤P%YyU{Y_gbM86c z{k}Qp>^+mIyHb0sgzP_8`iS`bJoFNPvvCOP<99)yq@dp%T*ZY5mkF~3-OJUlV5jMJ zX&|akl{->Xh`aIp_O=LfIhKcFCHnXl&^Hq3jX~@NAOzY9J;`2kBx@!leJ%m13h~Mb zak25ba^TOC%Ho^XD+b&VOM`gy8GNS~Nu$G6dLh~eZKdq8L*?3*vqz4a0xK(mSrOgG z*7Id#jP2peSN{b0*JWtSEdg1ge_K}NwV@tISMy%KT&?mjB>LH?D|iqQH+<8qehWi? zNL|g*7`>_RFh88jB?ZKy7&ldxl!W*?T|`9%ZGs5X7Xgyb{ll^I-@{(9F`nlpqU<(rSjBvg#f*U7&%Sh~tw0&}90MP+ z9j@}ypj{W%YX}Z4HBJR%lmi(+%Qi9H6=em&n!ww|`Z7$h0Dt$lfZh==){hP=tV!6( z4JfQnP`%iA^Td6M=)lYDwooGvD7vy)#sBa^YTQLo8T40KTr4A7S%df;**`cbo+sYS zD>?;`IV9J|ss?{tRztXt6?UiK8uz|wN(aY0X>#x}<%~xZj3{>U3FdkTyOh9v7ur3@ zH}{8%Ald7Nbca{V-lI{&;N+fJ>Nh%g&}Yy-q#nZ?$khH-3es1wuwj-K8FREyU5orE z=bp}RkUYa{b>~FTXQ|H^^@Ef|ZkLv z!_{-dtKQkXwNs;z#LDK!u>%SzxY|NI(+ctQ%wUzn3n+j@^BiDeB7t;*$kQ3KYeZ&S ze9HP>?#KzVo5MULaf;G?PM9YIl4j?ouv;PIw>!1$6$hm6V{9AxJ#4_2DD2~wO*ay; z2k=KZS_<_;_Dwp7QCdgTp1TlA9}ZD>hY zKv5uxTN;54AMLD9J#m8m3ntTw$+SyacAU!Wy_Xuwe7RgOM{$fIfa9tSP2r_#Jh1h8 z;*!{j<9AGnSF%n1ui0+-hoXK(kK>e?vvC*exy(HNN-kbGxXHhfs4svYEar|si)dNY z*3D6k#p+Y|xjPo`s$zYCRpbqJDG+531G}XQ0sN5Q3Rq8o8v*uia5=XSV4nteu8Rfp zC=Q3U%4{FCthLhiZ5LLuZ1B9=&F5M9C%}>gA-^lKZ8y)p2(OM*l;p!&C~vE5zda; + static __bss_end_inclusive: UnsafeCell; } //-------------------------------------------------------------------------------------------------- @@ -59,17 +59,12 @@ pub fn boot_core_stack_end() -> usize { map::BOOT_CORE_STACK_END } -/// Return the range spanning the .bss section. +/// Return the inclusive range spanning the .bss section. /// /// # Safety /// /// - Values are provided by the linker script and must be trusted as-is. /// - The linker-provided addresses must be u64 aligned. -pub fn bss_range() -> Range<*mut u64> { - unsafe { - Range { - start: &__bss_start as *const _ as *mut u64, - end: &__bss_end as *const _ as *mut u64, - } - } +pub fn bss_range_inclusive() -> RangeInclusive<*mut u64> { + unsafe { RangeInclusive::new(__bss_start.get(), __bss_end_inclusive.get()) } } diff --git a/X1_JTAG_boot/src/memory.rs b/X1_JTAG_boot/src/memory.rs index 7af7f898..77e21c0c 100644 --- a/X1_JTAG_boot/src/memory.rs +++ b/X1_JTAG_boot/src/memory.rs @@ -4,26 +4,31 @@ //! Memory Management. -use core::ops::Range; +use core::ops::RangeInclusive; //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory range. +/// Zero out an inclusive memory range. /// /// # Safety /// /// - `range.start` and `range.end` must be valid. /// - `range.start` and `range.end` must be `T` aligned. -pub unsafe fn zero_volatile(range: Range<*mut T>) +pub unsafe fn zero_volatile(range: RangeInclusive<*mut T>) where T: From, { - let mut ptr = range.start; + let mut ptr = *range.start(); + let end_inclusive = *range.end(); - while ptr < range.end { + loop { core::ptr::write_volatile(ptr, T::from(0)); ptr = ptr.offset(1); + + if ptr > end_inclusive { + break; + } } } diff --git a/X1_JTAG_boot/src/runtime_init.rs b/X1_JTAG_boot/src/runtime_init.rs index 42c8f6af..9de28595 100644 --- a/X1_JTAG_boot/src/runtime_init.rs +++ b/X1_JTAG_boot/src/runtime_init.rs @@ -17,7 +17,7 @@ use crate::{bsp, memory}; /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bsp::memory::bss_range()); + memory::zero_volatile(bsp::memory::bss_range_inclusive()); } //--------------------------------------------------------------------------------------------------