From 37b9d1435ef99a82839463e6b92f73b92f73ddc6 Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Mon, 28 Sep 2020 21:40:59 +0200 Subject: [PATCH] Move anything wrt linker symbols to bsp::memory Also, some rewording of data types. --- 02_runtime_init/README.md | 79 ++++++--- 02_runtime_init/src/bsp/raspberrypi.rs | 2 +- 02_runtime_init/src/bsp/raspberrypi/memory.rs | 36 ++++ 02_runtime_init/src/memory.rs | 2 +- 02_runtime_init/src/runtime_init.rs | 24 +-- 03_hacky_hello_world/README.md | 4 +- 03_hacky_hello_world/src/bsp/raspberrypi.rs | 1 + .../src/bsp/raspberrypi/memory.rs | 36 ++++ 03_hacky_hello_world/src/memory.rs | 2 +- 03_hacky_hello_world/src/runtime_init.rs | 24 +-- 04_zero_overhead_abstraction/README.md | 23 +-- .../src/bsp/raspberrypi/memory.rs | 31 ++++ 04_zero_overhead_abstraction/src/memory.rs | 2 +- .../src/runtime_init.rs | 24 +-- 05_safe_globals/src/bsp/raspberrypi/memory.rs | 31 ++++ 05_safe_globals/src/memory.rs | 2 +- 05_safe_globals/src/runtime_init.rs | 24 +-- 06_drivers_gpio_uart/README.md | 9 +- .../src/bsp/raspberrypi/memory.rs | 31 ++++ 06_drivers_gpio_uart/src/memory.rs | 2 +- 06_drivers_gpio_uart/src/runtime_init.rs | 24 +-- 07_uart_chainloader/README.md | 10 +- .../src/bsp/raspberrypi/memory.rs | 31 ++++ 07_uart_chainloader/src/memory.rs | 2 +- 07_uart_chainloader/src/runtime_init.rs | 24 +-- 08_timestamps/README.md | 10 +- 08_timestamps/src/bsp/raspberrypi/memory.rs | 31 ++++ 08_timestamps/src/memory.rs | 2 +- 08_timestamps/src/runtime_init.rs | 24 +-- .../src/bsp/raspberrypi/memory.rs | 31 ++++ 09_hw_debug_JTAG/src/memory.rs | 2 +- 09_hw_debug_JTAG/src/runtime_init.rs | 24 +-- .../src/bsp/raspberrypi/memory.rs | 31 ++++ 10_privilege_level/src/memory.rs | 2 +- 10_privilege_level/src/runtime_init.rs | 24 +-- 11_virtual_memory/README.md | 155 +++++++++++------- .../src/bsp/raspberrypi/memory.rs | 57 +++++++ .../src/bsp/raspberrypi/memory/mmu.rs | 65 ++++---- 11_virtual_memory/src/memory.rs | 2 +- 11_virtual_memory/src/memory/mmu.rs | 17 +- 11_virtual_memory/src/runtime_init.rs | 24 +-- 12_exceptions_part1_groundwork/README.md | 29 ++-- .../src/bsp/raspberrypi/memory.rs | 57 +++++++ .../src/bsp/raspberrypi/memory/mmu.rs | 51 +++--- 12_exceptions_part1_groundwork/src/memory.rs | 2 +- .../src/memory/mmu.rs | 17 +- .../src/runtime_init.rs | 24 +-- 13_integrated_testing/README.md | 12 +- .../src/bsp/raspberrypi/memory.rs | 57 +++++++ .../src/bsp/raspberrypi/memory/mmu.rs | 51 +++--- 13_integrated_testing/src/memory.rs | 2 +- 13_integrated_testing/src/memory/mmu.rs | 19 ++- 13_integrated_testing/src/runtime_init.rs | 28 +--- 14_exceptions_part2_peripheral_IRQs/README.md | 5 +- .../src/bsp/raspberrypi/memory.rs | 57 +++++++ .../src/bsp/raspberrypi/memory/mmu.rs | 51 +++--- .../src/memory.rs | 2 +- .../src/memory/mmu.rs | 19 ++- .../src/runtime_init.rs | 28 +--- X1_JTAG_boot/jtag_boot_rpi3.img | Bin 7104 -> 7104 bytes X1_JTAG_boot/jtag_boot_rpi4.img | Bin 7088 -> 7088 bytes X1_JTAG_boot/src/bsp/raspberrypi/memory.rs | 31 ++++ X1_JTAG_boot/src/memory.rs | 2 +- X1_JTAG_boot/src/runtime_init.rs | 24 +-- 64 files changed, 927 insertions(+), 622 deletions(-) create mode 100644 02_runtime_init/src/bsp/raspberrypi/memory.rs create mode 100644 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs diff --git a/02_runtime_init/README.md b/02_runtime_init/README.md index 1b592896..b7a8ae72 100644 --- a/02_runtime_init/README.md +++ b/02_runtime_init/README.md @@ -74,6 +74,57 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/ra /DISCARD/ : { *(.comment*) } } +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 @@ ++// SPDX-License-Identifier: MIT OR Apache-2.0 ++// ++// Copyright (c) 2018-2020 Andre Richter ++ ++//! BSP Memory Management. ++ ++use core::ops::Range; ++ ++//-------------------------------------------------------------------------------------------------- ++// Private Definitions ++//-------------------------------------------------------------------------------------------------- ++ ++// Symbols from the linker script. ++extern "C" { ++ static __bss_start: usize; ++ static __bss_end: usize; ++} ++ ++//-------------------------------------------------------------------------------------------------- ++// Public Code ++//-------------------------------------------------------------------------------------------------- ++ ++/// Return the 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, ++ } ++ } ++} + +diff -uNr 01_wait_forever/src/bsp/raspberrypi.rs 02_runtime_init/src/bsp/raspberrypi.rs +--- 01_wait_forever/src/bsp/raspberrypi.rs ++++ 02_runtime_init/src/bsp/raspberrypi.rs +@@ -4,4 +4,4 @@ + + //! Top-level BSP file for the Raspberry Pi 3 and 4. + +-// Coming soon. ++pub mod memory; + diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs --- 01_wait_forever/src/main.rs +++ 02_runtime_init/src/main.rs @@ -117,7 +168,7 @@ diff -uNr 01_wait_forever/src/memory.rs 02_runtime_init/src/memory.rs +// Public Code +//-------------------------------------------------------------------------------------------------- + -+/// Zero out a memory region. ++/// Zero out a memory range. +/// +/// # Safety +/// @@ -138,39 +189,19 @@ diff -uNr 01_wait_forever/src/memory.rs 02_runtime_init/src/memory.rs diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.rs --- 01_wait_forever/src/runtime_init.rs +++ 02_runtime_init/src/runtime_init.rs -@@ -0,0 +1,58 @@ +@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter + +//! Rust runtime initialization code. + -+use crate::memory; -+use core::ops::Range; ++use crate::{bsp, memory}; + +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + -+/// Return the range spanning the .bss section. -+/// -+/// # Safety -+/// -+/// - The symbol-provided addresses must be valid. -+/// - The symbol-provided addresses must be usize aligned. -+unsafe fn bss_range() -> Range<*mut usize> { -+ extern "C" { -+ // Boundaries of the .bss section, provided by linker script symbols. -+ static mut __bss_start: usize; -+ static mut __bss_end: usize; -+ } -+ -+ Range { -+ start: &mut __bss_start, -+ end: &mut __bss_end, -+ } -+} -+ +/// Zero out the .bss section. +/// +/// # Safety @@ -178,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(bss_range()); ++ memory::zero_volatile(bsp::memory::bss_range()); +} + +//-------------------------------------------------------------------------------------------------- diff --git a/02_runtime_init/src/bsp/raspberrypi.rs b/02_runtime_init/src/bsp/raspberrypi.rs index cdaac740..e4ecbd1d 100644 --- a/02_runtime_init/src/bsp/raspberrypi.rs +++ b/02_runtime_init/src/bsp/raspberrypi.rs @@ -4,4 +4,4 @@ //! Top-level BSP file for the Raspberry Pi 3 and 4. -// Coming soon. +pub mod memory; diff --git a/02_runtime_init/src/bsp/raspberrypi/memory.rs b/02_runtime_init/src/bsp/raspberrypi/memory.rs new file mode 100644 index 00000000..ea2ab84c --- /dev/null +++ b/02_runtime_init/src/bsp/raspberrypi/memory.rs @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter + +//! BSP Memory Management. + +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/02_runtime_init/src/memory.rs b/02_runtime_init/src/memory.rs index 71dc0292..7af7f898 100644 --- a/02_runtime_init/src/memory.rs +++ b/02_runtime_init/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/02_runtime_init/src/runtime_init.rs b/02_runtime_init/src/runtime_init.rs index ec43c9a6..90ef43c6 100644 --- a/02_runtime_init/src/runtime_init.rs +++ b/02_runtime_init/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/03_hacky_hello_world/README.md b/03_hacky_hello_world/README.md index 038ab888..5b97c3fa 100644 --- a/03_hacky_hello_world/README.md +++ b/03_hacky_hello_world/README.md @@ -105,12 +105,12 @@ diff -uNr 02_runtime_init/src/bsp/raspberrypi/console.rs 03_hacky_hello_world/sr diff -uNr 02_runtime_init/src/bsp/raspberrypi.rs 03_hacky_hello_world/src/bsp/raspberrypi.rs --- 02_runtime_init/src/bsp/raspberrypi.rs +++ 03_hacky_hello_world/src/bsp/raspberrypi.rs -@@ -4,4 +4,4 @@ +@@ -4,4 +4,5 @@ //! Top-level BSP file for the Raspberry Pi 3 and 4. --// Coming soon. +pub mod console; + pub mod memory; diff -uNr 02_runtime_init/src/console.rs 03_hacky_hello_world/src/console.rs --- 02_runtime_init/src/console.rs diff --git a/03_hacky_hello_world/src/bsp/raspberrypi.rs b/03_hacky_hello_world/src/bsp/raspberrypi.rs index f776e707..fba4f0a2 100644 --- a/03_hacky_hello_world/src/bsp/raspberrypi.rs +++ b/03_hacky_hello_world/src/bsp/raspberrypi.rs @@ -5,3 +5,4 @@ //! Top-level BSP file for the Raspberry Pi 3 and 4. pub mod console; +pub mod memory; diff --git a/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs b/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs new file mode 100644 index 00000000..ea2ab84c --- /dev/null +++ b/03_hacky_hello_world/src/bsp/raspberrypi/memory.rs @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter + +//! BSP Memory Management. + +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/03_hacky_hello_world/src/memory.rs b/03_hacky_hello_world/src/memory.rs index 71dc0292..7af7f898 100644 --- a/03_hacky_hello_world/src/memory.rs +++ b/03_hacky_hello_world/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/03_hacky_hello_world/src/runtime_init.rs b/03_hacky_hello_world/src/runtime_init.rs index ec43c9a6..90ef43c6 100644 --- a/03_hacky_hello_world/src/runtime_init.rs +++ b/03_hacky_hello_world/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/04_zero_overhead_abstraction/README.md b/04_zero_overhead_abstraction/README.md index ff4a6044..73c33a04 100644 --- a/04_zero_overhead_abstraction/README.md +++ b/04_zero_overhead_abstraction/README.md @@ -157,29 +157,30 @@ diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi/cpu.rs 04_zero_overhead_abstr diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs --- 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs +++ 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs -@@ -0,0 +1,12 @@ -+// SPDX-License-Identifier: MIT OR Apache-2.0 -+// -+// Copyright (c) 2018-2020 Andre Richter -+ -+//! BSP Memory Management. -+ -+//-------------------------------------------------------------------------------------------------- +@@ -17,6 +17,13 @@ + } + + //-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + +/// The early boot core's stack address. +pub const BOOT_CORE_STACK_START: usize = 0x80_000; ++ ++//-------------------------------------------------------------------------------------------------- + // Public Code + //-------------------------------------------------------------------------------------------------- + diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi.rs 04_zero_overhead_abstraction/src/bsp/raspberrypi.rs --- 03_hacky_hello_world/src/bsp/raspberrypi.rs +++ 04_zero_overhead_abstraction/src/bsp/raspberrypi.rs -@@ -5,3 +5,5 @@ +@@ -5,4 +5,5 @@ //! Top-level BSP file for the Raspberry Pi 3 and 4. pub mod console; +pub mod cpu; -+pub mod memory; + pub mod memory; diff -uNr 03_hacky_hello_world/src/cpu/smp.rs 04_zero_overhead_abstraction/src/cpu/smp.rs --- 03_hacky_hello_world/src/cpu/smp.rs @@ -235,7 +236,7 @@ diff -uNr 03_hacky_hello_world/src/main.rs 04_zero_overhead_abstraction/src/main diff -uNr 03_hacky_hello_world/src/runtime_init.rs 04_zero_overhead_abstraction/src/runtime_init.rs --- 03_hacky_hello_world/src/runtime_init.rs +++ 04_zero_overhead_abstraction/src/runtime_init.rs -@@ -50,8 +50,7 @@ +@@ -30,8 +30,7 @@ /// # Safety /// /// - Only a single core must be active and running this function. diff --git a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs index a9c4530b..fb073898 100644 --- a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs +++ b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs @@ -4,9 +4,40 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- /// The early boot core's stack address. pub const BOOT_CORE_STACK_START: usize = 0x80_000; + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/04_zero_overhead_abstraction/src/memory.rs b/04_zero_overhead_abstraction/src/memory.rs index 71dc0292..7af7f898 100644 --- a/04_zero_overhead_abstraction/src/memory.rs +++ b/04_zero_overhead_abstraction/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/04_zero_overhead_abstraction/src/runtime_init.rs b/04_zero_overhead_abstraction/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/04_zero_overhead_abstraction/src/runtime_init.rs +++ b/04_zero_overhead_abstraction/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/05_safe_globals/src/bsp/raspberrypi/memory.rs b/05_safe_globals/src/bsp/raspberrypi/memory.rs index a9c4530b..fb073898 100644 --- a/05_safe_globals/src/bsp/raspberrypi/memory.rs +++ b/05_safe_globals/src/bsp/raspberrypi/memory.rs @@ -4,9 +4,40 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- /// The early boot core's stack address. pub const BOOT_CORE_STACK_START: usize = 0x80_000; + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/05_safe_globals/src/memory.rs b/05_safe_globals/src/memory.rs index 71dc0292..7af7f898 100644 --- a/05_safe_globals/src/memory.rs +++ b/05_safe_globals/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/05_safe_globals/src/runtime_init.rs b/05_safe_globals/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/05_safe_globals/src/runtime_init.rs +++ b/05_safe_globals/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/06_drivers_gpio_uart/README.md b/06_drivers_gpio_uart/README.md index 085636ff..fa6db363 100644 --- a/06_drivers_gpio_uart/README.md +++ b/06_drivers_gpio_uart/README.md @@ -851,11 +851,10 @@ diff -uNr 05_safe_globals/src/bsp/raspberrypi/driver.rs 06_drivers_gpio_uart/src diff -uNr 05_safe_globals/src/bsp/raspberrypi/memory.rs 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs --- 05_safe_globals/src/bsp/raspberrypi/memory.rs +++ 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs -@@ -10,3 +10,30 @@ - +@@ -23,6 +23,33 @@ /// The early boot core's stack address. pub const BOOT_CORE_STACK_START: usize = 0x80_000; -+ + +/// The board's memory map. +#[rustfmt::skip] +pub(super) mod map { @@ -882,6 +881,10 @@ diff -uNr 05_safe_globals/src/bsp/raspberrypi/memory.rs 06_drivers_gpio_uart/src + pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + } +} ++ + //-------------------------------------------------------------------------------------------------- + // Public Code + //-------------------------------------------------------------------------------------------------- diff -uNr 05_safe_globals/src/bsp/raspberrypi.rs 06_drivers_gpio_uart/src/bsp/raspberrypi.rs --- 05_safe_globals/src/bsp/raspberrypi.rs diff --git a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs index 5f7d1c6b..90ff9b5b 100644 --- a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs +++ b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs @@ -4,6 +4,18 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -37,3 +49,22 @@ pub(super) mod map { pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/06_drivers_gpio_uart/src/memory.rs b/06_drivers_gpio_uart/src/memory.rs index 71dc0292..7af7f898 100644 --- a/06_drivers_gpio_uart/src/memory.rs +++ b/06_drivers_gpio_uart/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/06_drivers_gpio_uart/src/runtime_init.rs b/06_drivers_gpio_uart/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/06_drivers_gpio_uart/src/runtime_init.rs +++ b/06_drivers_gpio_uart/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/07_uart_chainloader/README.md b/07_uart_chainloader/README.md index 9edf9e7b..6322134f 100644 --- a/07_uart_chainloader/README.md +++ b/07_uart_chainloader/README.md @@ -281,7 +281,7 @@ diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld 07_uart_chainloader/s diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs 07_uart_chainloader/src/bsp/raspberrypi/memory.rs --- 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs +++ 07_uart_chainloader/src/bsp/raspberrypi/memory.rs -@@ -11,6 +11,9 @@ +@@ -23,6 +23,9 @@ /// The early boot core's stack address. pub const BOOT_CORE_STACK_START: usize = 0x80_000; @@ -476,8 +476,8 @@ diff -uNr 06_drivers_gpio_uart/src/relocate.rs 07_uart_chainloader/src/relocate. diff -uNr 06_drivers_gpio_uart/src/runtime_init.rs 07_uart_chainloader/src/runtime_init.rs --- 06_drivers_gpio_uart/src/runtime_init.rs +++ 07_uart_chainloader/src/runtime_init.rs -@@ -8,9 +8,43 @@ - use core::ops::Range; +@@ -7,9 +7,43 @@ + use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- +// Private Definitions @@ -517,10 +517,10 @@ diff -uNr 06_drivers_gpio_uart/src/runtime_init.rs 07_uart_chainloader/src/runti +impl RunTimeInit for Traitor {} + - /// Return the range spanning the .bss section. + /// Zero out the .bss section. /// /// # Safety -@@ -44,14 +78,7 @@ +@@ -24,14 +58,7 @@ // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs index ef78753c..08b9034e 100644 --- a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs +++ b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs @@ -4,6 +4,18 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -40,3 +52,22 @@ pub(super) mod map { pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/07_uart_chainloader/src/memory.rs b/07_uart_chainloader/src/memory.rs index 71dc0292..7af7f898 100644 --- a/07_uart_chainloader/src/memory.rs +++ b/07_uart_chainloader/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/07_uart_chainloader/src/runtime_init.rs b/07_uart_chainloader/src/runtime_init.rs index 49c5a84c..c98c9172 100644 --- a/07_uart_chainloader/src/runtime_init.rs +++ b/07_uart_chainloader/src/runtime_init.rs @@ -4,8 +4,7 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Definitions @@ -45,25 +44,6 @@ pub trait RunTimeInit { impl RunTimeInit for Traitor {} -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -71,7 +51,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/08_timestamps/README.md b/08_timestamps/README.md index 131efdb2..0cc78a84 100644 --- a/08_timestamps/README.md +++ b/08_timestamps/README.md @@ -284,7 +284,7 @@ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/link.ld 08_timestamps/src/bsp/ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/memory.rs 08_timestamps/src/bsp/raspberrypi/memory.rs --- 07_uart_chainloader/src/bsp/raspberrypi/memory.rs +++ 08_timestamps/src/bsp/raspberrypi/memory.rs -@@ -11,9 +11,6 @@ +@@ -23,9 +23,6 @@ /// The early boot core's stack address. pub const BOOT_CORE_STACK_START: usize = 0x80_000; @@ -543,8 +543,8 @@ diff -uNr 07_uart_chainloader/src/relocate.rs 08_timestamps/src/relocate.rs diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init.rs --- 07_uart_chainloader/src/runtime_init.rs +++ 08_timestamps/src/runtime_init.rs -@@ -8,43 +8,9 @@ - use core::ops::Range; +@@ -7,43 +7,9 @@ + use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- -// Private Definitions @@ -584,10 +584,10 @@ diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init -impl RunTimeInit for Traitor {} - - /// Return the range spanning the .bss section. + /// Zero out the .bss section. /// /// # Safety -@@ -78,7 +44,14 @@ +@@ -58,7 +24,14 @@ // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/08_timestamps/src/bsp/raspberrypi/memory.rs b/08_timestamps/src/bsp/raspberrypi/memory.rs index 5f7d1c6b..90ff9b5b 100644 --- a/08_timestamps/src/bsp/raspberrypi/memory.rs +++ b/08_timestamps/src/bsp/raspberrypi/memory.rs @@ -4,6 +4,18 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -37,3 +49,22 @@ pub(super) mod map { pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/08_timestamps/src/memory.rs b/08_timestamps/src/memory.rs index 71dc0292..7af7f898 100644 --- a/08_timestamps/src/memory.rs +++ b/08_timestamps/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/08_timestamps/src/runtime_init.rs b/08_timestamps/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/08_timestamps/src/runtime_init.rs +++ b/08_timestamps/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs index 5f7d1c6b..90ff9b5b 100644 --- a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs +++ b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs @@ -4,6 +4,18 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -37,3 +49,22 @@ pub(super) mod map { pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/09_hw_debug_JTAG/src/memory.rs b/09_hw_debug_JTAG/src/memory.rs index 71dc0292..7af7f898 100644 --- a/09_hw_debug_JTAG/src/memory.rs +++ b/09_hw_debug_JTAG/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/09_hw_debug_JTAG/src/runtime_init.rs b/09_hw_debug_JTAG/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/09_hw_debug_JTAG/src/runtime_init.rs +++ b/09_hw_debug_JTAG/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/10_privilege_level/src/bsp/raspberrypi/memory.rs b/10_privilege_level/src/bsp/raspberrypi/memory.rs index 5f7d1c6b..90ff9b5b 100644 --- a/10_privilege_level/src/bsp/raspberrypi/memory.rs +++ b/10_privilege_level/src/bsp/raspberrypi/memory.rs @@ -4,6 +4,18 @@ //! BSP Memory Management. +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// Private Definitions +//-------------------------------------------------------------------------------------------------- + +// Symbols from the linker script. +extern "C" { + static __bss_start: usize; + static __bss_end: usize; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -37,3 +49,22 @@ pub(super) mod map { pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/10_privilege_level/src/memory.rs b/10_privilege_level/src/memory.rs index 71dc0292..7af7f898 100644 --- a/10_privilege_level/src/memory.rs +++ b/10_privilege_level/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/10_privilege_level/src/runtime_init.rs b/10_privilege_level/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/10_privilege_level/src/runtime_init.rs +++ b/10_privilege_level/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/11_virtual_memory/README.md b/11_virtual_memory/README.md index 3a0c177f..599108e1 100644 --- a/11_virtual_memory/README.md +++ b/11_virtual_memory/README.md @@ -46,7 +46,7 @@ Back from reading `Chapter 12` already? Good job :+1:! for composing a high-level data structure that describes the kernel's virtual memory layout: `memory::mmu::KernelVirtualLayout`. 2. The `BSP` part: `src/bsp/raspberrypi/memory/mmu.rs` contains a static instance of - `KernelVirtualLayout` and makes it accessible throug the function + `KernelVirtualLayout` and makes it accessible through the function `bsp::memory::mmu::virt_mem_layout()`. 3. The `aarch64` part: `src/_arch/aarch64/memory/mmu.rs` contains the actual `MMU` driver. It picks up the `BSP`'s high-level `KernelVirtualLayout` and maps it using a `64 KiB` granule. @@ -54,7 +54,7 @@ Back from reading `Chapter 12` already? Good job :+1:! ### Generic Kernel code: `memory/mmu.rs` The descriptor types provided in this file are building blocks which help to describe attributes of -different memory regions. For example, R/W, no-execute, cached/uncached, and so on. +different memory regions. For example, `R/W`, `no-execute`, `cached/uncached`, and so on. The descriptors are agnostic of the hardware `MMU`'s actual descriptors. Different `BSP`s can use these types to produce a high-level description of the kernel's virtual memory layout. The actual @@ -74,12 +74,10 @@ nothing prevents you from defining those too if you wish to. Here is an example region: ```rust -RangeDescriptor { +TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory::map::mmio::BASE, memory::map::mmio::END_INCLUSIVE) - }, - translation: Translation::Identity, + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, @@ -98,10 +96,11 @@ pub fn virt_addr_properties( ``` It will be used by the `_arch/aarch64`'s `MMU` code to request attributes for a virtual address and -the translation of the address. The function scans for a descriptor that contains the queried -address, and returns the respective findings for the first entry that is a hit. If no entry is -found, it returns default attributes for normal chacheable DRAM and the input address, hence telling -the `MMU` code that the requested address should be `identity mapped`. +the translation, which delivers the physical output address (the `usize` in the return-tuple). The +function scans for a descriptor that contains the queried address, and returns the respective +findings for the first entry that is a hit. If no entry is found, it returns default attributes for +normal chacheable DRAM and the input address, hence telling the `MMU` code that the requested +address should be `identity mapped`. Due to this default return, it is technicall not needed to define normal cacheable DRAM regions. @@ -644,7 +643,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/link.ld 11_virtual_memory/src/b diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory/mmu.rs 11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs --- 10_privilege_level/src/bsp/raspberrypi/memory/mmu.rs +++ 11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs -@@ -0,0 +1,97 @@ +@@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter @@ -668,58 +667,30 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory/mmu.rs 11_virtual_memory +pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( + memory_map::END_INCLUSIVE, + [ -+ RangeDescriptor { ++ TranslationDescriptor { + name: "Kernel code and RO data", -+ virtual_range: || { -+ // Using the linker script, we ensure that the RO area is consecutive and 64 KiB -+ // aligned, and we export the boundaries via symbols: -+ // -+ // [__ro_start, __ro_end) -+ extern "C" { -+ // The inclusive start of the read-only area, aka the address of the first -+ // byte of the area. -+ static __ro_start: usize; -+ -+ // The exclusive end of the read-only area, aka the address of the first -+ // byte _after_ the RO area. -+ static __ro_end: usize; -+ } -+ -+ unsafe { -+ // Notice the subtraction to turn the exclusive end into an inclusive end. -+ #[allow(clippy::range_minus_one)] -+ RangeInclusive::new( -+ &__ro_start as *const _ as usize, -+ &__ro_end as *const _ as usize - 1, -+ ) -+ } -+ }, -+ translation: Translation::Identity, ++ virtual_range: ro_range_inclusive, ++ physical_range_translation: Translation::Identity, + attribute_fields: AttributeFields { + mem_attributes: MemAttributes::CacheableDRAM, + acc_perms: AccessPermissions::ReadOnly, + execute_never: false, + }, + }, -+ RangeDescriptor { ++ TranslationDescriptor { + name: "Remapped Device MMIO", -+ virtual_range: || { -+ // The last 64 KiB slot in the first 512 MiB -+ RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) -+ }, -+ translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), ++ virtual_range: remapped_mmio_range_inclusive, ++ physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), + attribute_fields: AttributeFields { + mem_attributes: MemAttributes::Device, + acc_perms: AccessPermissions::ReadWrite, + execute_never: true, + }, + }, -+ RangeDescriptor { ++ TranslationDescriptor { + name: "Device MMIO", -+ virtual_range: || { -+ RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) -+ }, -+ translation: Translation::Identity, ++ virtual_range: mmio_range_inclusive, ++ physical_range_translation: Translation::Identity, + attribute_fields: AttributeFields { + mem_attributes: MemAttributes::Device, + acc_perms: AccessPermissions::ReadWrite, @@ -730,6 +701,25 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory/mmu.rs 11_virtual_memory +); + +//-------------------------------------------------------------------------------------------------- ++// Private Code ++//-------------------------------------------------------------------------------------------------- ++ ++fn ro_range_inclusive() -> RangeInclusive { ++ // Notice the subtraction to turn the exclusive end into an inclusive end. ++ #[allow(clippy::range_minus_one)] ++ RangeInclusive::new(super::ro_start(), super::ro_end() - 1) ++} ++ ++fn remapped_mmio_range_inclusive() -> RangeInclusive { ++ // The last 64 KiB slot in the first 512 MiB ++ RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) ++} ++ ++fn mmio_range_inclusive() -> RangeInclusive { ++ RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) ++} ++ ++//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + @@ -752,10 +742,19 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src +pub mod mmu; + + use core::ops::Range; + //-------------------------------------------------------------------------------------------------- - // Public Definitions - //-------------------------------------------------------------------------------------------------- -@@ -14,6 +16,8 @@ +@@ -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; + } +@@ -26,6 +30,8 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { @@ -764,7 +763,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; -@@ -25,6 +29,7 @@ +@@ -37,6 +43,7 @@ pub const BASE: usize = 0x3F00_0000; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; @@ -772,7 +771,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src } /// Physical devices. -@@ -35,5 +40,6 @@ +@@ -47,10 +54,35 @@ pub const BASE: usize = 0xFE00_0000; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; @@ -780,6 +779,35 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src } } + //-------------------------------------------------------------------------------------------------- ++// Private Code ++//-------------------------------------------------------------------------------------------------- ++ ++/// Start address of the Read-Only (RO) range. ++/// ++/// # Safety ++/// ++/// - 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 } ++} ++ ++/// Size of the Read-Only (RO) range of the kernel binary. ++/// ++/// # Safety ++/// ++/// - 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 } ++} ++ ++//-------------------------------------------------------------------------------------------------- + // Public Code + //-------------------------------------------------------------------------------------------------- + + diff -uNr 10_privilege_level/src/bsp.rs 11_virtual_memory/src/bsp.rs --- 10_privilege_level/src/bsp.rs +++ 11_virtual_memory/src/bsp.rs @@ -866,7 +894,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu.rs --- 10_privilege_level/src/memory/mmu.rs +++ 11_virtual_memory/src/memory/mmu.rs -@@ -0,0 +1,198 @@ +@@ -0,0 +1,199 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2020 Andre Richter @@ -944,10 +972,10 @@ diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu. + +/// Architecture agnostic descriptor for a memory range. +#[allow(missing_docs)] -+pub struct RangeDescriptor { ++pub struct TranslationDescriptor { + pub name: &'static str, + pub virtual_range: fn() -> RangeInclusive, -+ pub translation: Translation, ++ pub physical_range_translation: Translation, + pub attribute_fields: AttributeFields, +} + @@ -957,7 +985,7 @@ diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu. + max_virt_addr_inclusive: usize, + + /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. -+ inner: [RangeDescriptor; NUM_SPECIAL_RANGES], ++ inner: [TranslationDescriptor; NUM_SPECIAL_RANGES], +} + +//-------------------------------------------------------------------------------------------------- @@ -974,8 +1002,8 @@ diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu. + } +} + -+/// Human-readable output of a RangeDescriptor. -+impl fmt::Display for RangeDescriptor { ++/// Human-readable output of a TranslationDescriptor. ++impl fmt::Display for TranslationDescriptor { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + // Call the function to which self.range points, and dereference the result, which causes + // Rust to copy the value. @@ -1023,14 +1051,15 @@ diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu. + +impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { + /// Create a new instance. -+ pub const fn new(max: usize, layout: [RangeDescriptor; NUM_SPECIAL_RANGES]) -> Self { ++ pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self { + Self { + max_virt_addr_inclusive: max, + inner: layout, + } + } + -+ /// For a virtual address, find and return the output address and corresponding attributes. ++ /// For a virtual address, find and return the physical output address and corresponding ++ /// attributes. + /// + /// If the address is not found in `inner`, return an identity mapped default with normal + /// cacheable DRAM attributes. @@ -1044,7 +1073,7 @@ diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu. + + for i in self.inner.iter() { + if (i.virtual_range)().contains(&virt_addr) { -+ let output_addr = match i.translation { ++ let output_addr = match i.physical_range_translation { + Translation::Identity => virt_addr, + Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), + }; diff --git a/11_virtual_memory/src/bsp/raspberrypi/memory.rs b/11_virtual_memory/src/bsp/raspberrypi/memory.rs index 2b34e84e..dab98a9e 100644 --- a/11_virtual_memory/src/bsp/raspberrypi/memory.rs +++ b/11_virtual_memory/src/bsp/raspberrypi/memory.rs @@ -6,6 +6,20 @@ pub mod mmu; +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// 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; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -43,3 +57,46 @@ pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFF84_FFFF; } } + +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +/// Start address of the Read-Only (RO) range. +/// +/// # Safety +/// +/// - 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 } +} + +/// Size of the Read-Only (RO) range of the kernel binary. +/// +/// # Safety +/// +/// - 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 } +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs b/11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs index 56b06716..ab100089 100644 --- a/11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs +++ b/11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs @@ -21,58 +21,30 @@ const NUM_MEM_RANGES: usize = 3; pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( memory_map::END_INCLUSIVE, [ - RangeDescriptor { + TranslationDescriptor { name: "Kernel code and RO data", - virtual_range: || { - // Using the linker script, we ensure that the RO area is consecutive and 64 KiB - // aligned, and we export the boundaries via symbols: - // - // [__ro_start, __ro_end) - extern "C" { - // The inclusive start of the read-only area, aka the address of the first - // byte of the area. - static __ro_start: usize; - - // The exclusive end of the read-only area, aka the address of the first - // byte _after_ the RO area. - static __ro_end: usize; - } - - unsafe { - // Notice the subtraction to turn the exclusive end into an inclusive end. - #[allow(clippy::range_minus_one)] - RangeInclusive::new( - &__ro_start as *const _ as usize, - &__ro_end as *const _ as usize - 1, - ) - } - }, - translation: Translation::Identity, + virtual_range: ro_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::CacheableDRAM, acc_perms: AccessPermissions::ReadOnly, execute_never: false, }, }, - RangeDescriptor { + TranslationDescriptor { name: "Remapped Device MMIO", - virtual_range: || { - // The last 64 KiB slot in the first 512 MiB - RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) - }, - translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), + virtual_range: remapped_mmio_range_inclusive, + physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, execute_never: true, }, }, - RangeDescriptor { + TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) - }, - translation: Translation::Identity, + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, @@ -82,6 +54,25 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout ], ); +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +fn ro_range_inclusive() -> RangeInclusive { + // Notice the subtraction to turn the exclusive end into an inclusive end. + #[allow(clippy::range_minus_one)] + RangeInclusive::new(super::ro_start(), super::ro_end() - 1) +} + +fn remapped_mmio_range_inclusive() -> RangeInclusive { + // The last 64 KiB slot in the first 512 MiB + RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) +} + +fn mmio_range_inclusive() -> RangeInclusive { + RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/11_virtual_memory/src/memory.rs b/11_virtual_memory/src/memory.rs index 989fa21f..40969f94 100644 --- a/11_virtual_memory/src/memory.rs +++ b/11_virtual_memory/src/memory.rs @@ -12,7 +12,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/11_virtual_memory/src/memory/mmu.rs b/11_virtual_memory/src/memory/mmu.rs index 7725641e..9675b8ab 100644 --- a/11_virtual_memory/src/memory/mmu.rs +++ b/11_virtual_memory/src/memory/mmu.rs @@ -75,10 +75,10 @@ pub struct AttributeFields { /// Architecture agnostic descriptor for a memory range. #[allow(missing_docs)] -pub struct RangeDescriptor { +pub struct TranslationDescriptor { pub name: &'static str, pub virtual_range: fn() -> RangeInclusive, - pub translation: Translation, + pub physical_range_translation: Translation, pub attribute_fields: AttributeFields, } @@ -88,7 +88,7 @@ pub struct KernelVirtualLayout { max_virt_addr_inclusive: usize, /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. - inner: [RangeDescriptor; NUM_SPECIAL_RANGES], + inner: [TranslationDescriptor; NUM_SPECIAL_RANGES], } //-------------------------------------------------------------------------------------------------- @@ -105,8 +105,8 @@ impl Default for AttributeFields { } } -/// Human-readable output of a RangeDescriptor. -impl fmt::Display for RangeDescriptor { +/// Human-readable output of a TranslationDescriptor. +impl fmt::Display for TranslationDescriptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Call the function to which self.range points, and dereference the result, which causes // Rust to copy the value. @@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor { impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { /// Create a new instance. - pub const fn new(max: usize, layout: [RangeDescriptor; NUM_SPECIAL_RANGES]) -> Self { + pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self { Self { max_virt_addr_inclusive: max, inner: layout, } } - /// For a virtual address, find and return the output address and corresponding attributes. + /// For a virtual address, find and return the physical output address and corresponding + /// attributes. /// /// If the address is not found in `inner`, return an identity mapped default with normal /// cacheable DRAM attributes. @@ -175,7 +176,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } for i in self.inner.iter() { if (i.virtual_range)().contains(&virt_addr) { - let output_addr = match i.translation { + let output_addr = match i.physical_range_translation { Translation::Identity => virt_addr, Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), }; diff --git a/11_virtual_memory/src/runtime_init.rs b/11_virtual_memory/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/11_virtual_memory/src/runtime_init.rs +++ b/11_virtual_memory/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/12_exceptions_part1_groundwork/README.md b/12_exceptions_part1_groundwork/README.md index ccc80aaa..13a1ba66 100644 --- a/12_exceptions_part1_groundwork/README.md +++ b/12_exceptions_part1_groundwork/README.md @@ -911,26 +911,35 @@ diff -uNr 11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs 12_exceptions_part /// The virtual memory layout. /// -@@ -55,19 +55,6 @@ +@@ -32,16 +32,6 @@ }, }, - RangeDescriptor { + TranslationDescriptor { - name: "Remapped Device MMIO", -- virtual_range: || { -- // The last 64 KiB slot in the first 512 MiB -- RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) -- }, -- translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), +- virtual_range: remapped_mmio_range_inclusive, +- physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000), - attribute_fields: AttributeFields { - mem_attributes: MemAttributes::Device, - acc_perms: AccessPermissions::ReadWrite, - execute_never: true, - }, - }, -- RangeDescriptor { +- TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, +@@ -64,11 +54,6 @@ + RangeInclusive::new(super::ro_start(), super::ro_end() - 1) + } + +-fn remapped_mmio_range_inclusive() -> RangeInclusive { +- // The last 64 KiB slot in the first 512 MiB +- RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF) +-} +- + fn mmio_range_inclusive() -> RangeInclusive { + RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) + } diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1_groundwork/src/bsp.rs --- 11_virtual_memory/src/bsp.rs diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs index 2b34e84e..dab98a9e 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs @@ -6,6 +6,20 @@ pub mod mmu; +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// 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; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -43,3 +57,46 @@ pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFF84_FFFF; } } + +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +/// Start address of the Read-Only (RO) range. +/// +/// # Safety +/// +/// - 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 } +} + +/// Size of the Read-Only (RO) range of the kernel binary. +/// +/// # Safety +/// +/// - 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 } +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs index dea366d3..1f702192 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs @@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2; pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( memory_map::END_INCLUSIVE, [ - RangeDescriptor { + TranslationDescriptor { name: "Kernel code and RO data", - virtual_range: || { - // Using the linker script, we ensure that the RO area is consecutive and 64 KiB - // aligned, and we export the boundaries via symbols: - // - // [__ro_start, __ro_end) - extern "C" { - // The inclusive start of the read-only area, aka the address of the first - // byte of the area. - static __ro_start: usize; - - // The exclusive end of the read-only area, aka the address of the first - // byte _after_ the RO area. - static __ro_end: usize; - } - - unsafe { - // Notice the subtraction to turn the exclusive end into an inclusive end. - #[allow(clippy::range_minus_one)] - RangeInclusive::new( - &__ro_start as *const _ as usize, - &__ro_end as *const _ as usize - 1, - ) - } - }, - translation: Translation::Identity, + virtual_range: ro_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::CacheableDRAM, acc_perms: AccessPermissions::ReadOnly, execute_never: false, }, }, - RangeDescriptor { + TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) - }, - translation: Translation::Identity, + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, @@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout ], ); +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +fn ro_range_inclusive() -> RangeInclusive { + // Notice the subtraction to turn the exclusive end into an inclusive end. + #[allow(clippy::range_minus_one)] + RangeInclusive::new(super::ro_start(), super::ro_end() - 1) +} + +fn mmio_range_inclusive() -> RangeInclusive { + RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/12_exceptions_part1_groundwork/src/memory.rs b/12_exceptions_part1_groundwork/src/memory.rs index 989fa21f..40969f94 100644 --- a/12_exceptions_part1_groundwork/src/memory.rs +++ b/12_exceptions_part1_groundwork/src/memory.rs @@ -12,7 +12,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/12_exceptions_part1_groundwork/src/memory/mmu.rs b/12_exceptions_part1_groundwork/src/memory/mmu.rs index d8270bfd..25a18bf9 100644 --- a/12_exceptions_part1_groundwork/src/memory/mmu.rs +++ b/12_exceptions_part1_groundwork/src/memory/mmu.rs @@ -76,10 +76,10 @@ pub struct AttributeFields { /// Architecture agnostic descriptor for a memory range. #[allow(missing_docs)] -pub struct RangeDescriptor { +pub struct TranslationDescriptor { pub name: &'static str, pub virtual_range: fn() -> RangeInclusive, - pub translation: Translation, + pub physical_range_translation: Translation, pub attribute_fields: AttributeFields, } @@ -89,7 +89,7 @@ pub struct KernelVirtualLayout { max_virt_addr_inclusive: usize, /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. - inner: [RangeDescriptor; NUM_SPECIAL_RANGES], + inner: [TranslationDescriptor; NUM_SPECIAL_RANGES], } //-------------------------------------------------------------------------------------------------- @@ -106,8 +106,8 @@ impl Default for AttributeFields { } } -/// Human-readable output of a RangeDescriptor. -impl fmt::Display for RangeDescriptor { +/// Human-readable output of a TranslationDescriptor. +impl fmt::Display for TranslationDescriptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Call the function to which self.range points, and dereference the result, which causes // Rust to copy the value. @@ -155,14 +155,15 @@ impl fmt::Display for RangeDescriptor { impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { /// Create a new instance. - pub const fn new(max: usize, layout: [RangeDescriptor; NUM_SPECIAL_RANGES]) -> Self { + pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self { Self { max_virt_addr_inclusive: max, inner: layout, } } - /// For a virtual address, find and return the output address and corresponding attributes. + /// For a virtual address, find and return the physical output address and corresponding + /// attributes. /// /// If the address is not found in `inner`, return an identity mapped default with normal /// cacheable DRAM attributes. @@ -176,7 +177,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } for i in self.inner.iter() { if (i.virtual_range)().contains(&virt_addr) { - let output_addr = match i.translation { + let output_addr = match i.physical_range_translation { Translation::Identity => virt_addr, Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), }; diff --git a/12_exceptions_part1_groundwork/src/runtime_init.rs b/12_exceptions_part1_groundwork/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/12_exceptions_part1_groundwork/src/runtime_init.rs +++ b/12_exceptions_part1_groundwork/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- diff --git a/13_integrated_testing/README.md b/13_integrated_testing/README.md index 4169f9e5..cf1f699a 100644 --- a/13_integrated_testing/README.md +++ b/13_integrated_testing/README.md @@ -1000,7 +1000,7 @@ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/console.rs 13_integ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs 13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs --- 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs +++ 13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs -@@ -82,3 +82,28 @@ +@@ -71,3 +71,28 @@ pub fn virt_mem_layout() -> &'static KernelVirtualLayout<{ NUM_MEM_RANGES }> { &LAYOUT } @@ -1462,13 +1462,13 @@ diff -uNr 12_exceptions_part1_groundwork/src/memory/mmu.rs 13_integrated_testing #[derive(Copy, Clone)] pub enum Translation { Identity, -@@ -196,4 +195,9 @@ +@@ -197,4 +196,9 @@ info!("{}", i); } } + + #[cfg(test)] -+ pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { ++ pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] { + &self.inner + } } @@ -1551,7 +1551,7 @@ 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 -@@ -51,7 +51,33 @@ +@@ -31,7 +31,33 @@ /// /// - Only a single core must be active and running this function. pub unsafe fn runtime_init() -> ! { @@ -1577,8 +1577,8 @@ diff -uNr 12_exceptions_part1_groundwork/src/runtime_init.rs 13_integrated_testi + fn bss_section_is_sane() { + use core::mem; + -+ let start = unsafe { bss_range().start } as *const _ as usize; -+ let end = unsafe { bss_range().end } as *const _ as usize; ++ 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); diff --git a/13_integrated_testing/src/bsp/raspberrypi/memory.rs b/13_integrated_testing/src/bsp/raspberrypi/memory.rs index 2b34e84e..dab98a9e 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/memory.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/memory.rs @@ -6,6 +6,20 @@ pub mod mmu; +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// 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; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -43,3 +57,46 @@ pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFF84_FFFF; } } + +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +/// Start address of the Read-Only (RO) range. +/// +/// # Safety +/// +/// - 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 } +} + +/// Size of the Read-Only (RO) range of the kernel binary. +/// +/// # Safety +/// +/// - 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 } +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs b/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs index 31c6f9a6..578591de 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs @@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2; pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( memory_map::END_INCLUSIVE, [ - RangeDescriptor { + TranslationDescriptor { name: "Kernel code and RO data", - virtual_range: || { - // Using the linker script, we ensure that the RO area is consecutive and 64 KiB - // aligned, and we export the boundaries via symbols: - // - // [__ro_start, __ro_end) - extern "C" { - // The inclusive start of the read-only area, aka the address of the first - // byte of the area. - static __ro_start: usize; - - // The exclusive end of the read-only area, aka the address of the first - // byte _after_ the RO area. - static __ro_end: usize; - } - - unsafe { - // Notice the subtraction to turn the exclusive end into an inclusive end. - #[allow(clippy::range_minus_one)] - RangeInclusive::new( - &__ro_start as *const _ as usize, - &__ro_end as *const _ as usize - 1, - ) - } - }, - translation: Translation::Identity, + virtual_range: ro_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::CacheableDRAM, acc_perms: AccessPermissions::ReadOnly, execute_never: false, }, }, - RangeDescriptor { + TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) - }, - translation: Translation::Identity, + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, @@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout ], ); +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +fn ro_range_inclusive() -> RangeInclusive { + // Notice the subtraction to turn the exclusive end into an inclusive end. + #[allow(clippy::range_minus_one)] + RangeInclusive::new(super::ro_start(), super::ro_end() - 1) +} + +fn mmio_range_inclusive() -> RangeInclusive { + RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/13_integrated_testing/src/memory.rs b/13_integrated_testing/src/memory.rs index 4a68a6d9..65d4b92b 100644 --- a/13_integrated_testing/src/memory.rs +++ b/13_integrated_testing/src/memory.rs @@ -12,7 +12,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/13_integrated_testing/src/memory/mmu.rs b/13_integrated_testing/src/memory/mmu.rs index 9a4885bd..39f3ef3c 100644 --- a/13_integrated_testing/src/memory/mmu.rs +++ b/13_integrated_testing/src/memory/mmu.rs @@ -75,10 +75,10 @@ pub struct AttributeFields { /// Architecture agnostic descriptor for a memory range. #[allow(missing_docs)] -pub struct RangeDescriptor { +pub struct TranslationDescriptor { pub name: &'static str, pub virtual_range: fn() -> RangeInclusive, - pub translation: Translation, + pub physical_range_translation: Translation, pub attribute_fields: AttributeFields, } @@ -88,7 +88,7 @@ pub struct KernelVirtualLayout { max_virt_addr_inclusive: usize, /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. - inner: [RangeDescriptor; NUM_SPECIAL_RANGES], + inner: [TranslationDescriptor; NUM_SPECIAL_RANGES], } //-------------------------------------------------------------------------------------------------- @@ -105,8 +105,8 @@ impl Default for AttributeFields { } } -/// Human-readable output of a RangeDescriptor. -impl fmt::Display for RangeDescriptor { +/// Human-readable output of a TranslationDescriptor. +impl fmt::Display for TranslationDescriptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Call the function to which self.range points, and dereference the result, which causes // Rust to copy the value. @@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor { impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { /// Create a new instance. - pub const fn new(max: usize, layout: [RangeDescriptor; NUM_SPECIAL_RANGES]) -> Self { + pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self { Self { max_virt_addr_inclusive: max, inner: layout, } } - /// For a virtual address, find and return the output address and corresponding attributes. + /// For a virtual address, find and return the physical output address and corresponding + /// attributes. /// /// If the address is not found in `inner`, return an identity mapped default with normal /// cacheable DRAM attributes. @@ -175,7 +176,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } for i in self.inner.iter() { if (i.virtual_range)().contains(&virt_addr) { - let output_addr = match i.translation { + let output_addr = match i.physical_range_translation { Translation::Identity => virt_addr, Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), }; @@ -197,7 +198,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } } #[cfg(test)] - pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { + pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] { &self.inner } } diff --git a/13_integrated_testing/src/runtime_init.rs b/13_integrated_testing/src/runtime_init.rs index 04cca287..a882dbe3 100644 --- a/13_integrated_testing/src/runtime_init.rs +++ b/13_integrated_testing/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- @@ -73,8 +53,8 @@ mod tests { fn bss_section_is_sane() { use core::mem; - let start = unsafe { bss_range().start } as *const _ as usize; - let end = unsafe { bss_range().end } as *const _ as usize; + 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); diff --git a/14_exceptions_part2_peripheral_IRQs/README.md b/14_exceptions_part2_peripheral_IRQs/README.md index 0e9bd694..0c152be2 100644 --- a/14_exceptions_part2_peripheral_IRQs/README.md +++ b/14_exceptions_part2_peripheral_IRQs/README.md @@ -2145,7 +2145,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/exception.rs 14_exceptions_p diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs --- 13_integrated_testing/src/bsp/raspberrypi/memory.rs +++ 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs -@@ -16,20 +16,22 @@ +@@ -30,20 +30,22 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { @@ -2175,7 +2175,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part } /// Physical devices. -@@ -37,9 +39,11 @@ +@@ -51,10 +53,12 @@ pub mod mmio { use super::*; @@ -2192,6 +2192,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part } } + diff -uNr 13_integrated_testing/src/bsp/raspberrypi.rs 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs --- 13_integrated_testing/src/bsp/raspberrypi.rs +++ 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs 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 2bed136c..58abdb9e 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs @@ -6,6 +6,20 @@ pub mod mmu; +use core::ops::Range; + +//-------------------------------------------------------------------------------------------------- +// 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; +} + //-------------------------------------------------------------------------------------------------- // Public Definitions //-------------------------------------------------------------------------------------------------- @@ -47,3 +61,46 @@ pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFF84_FFFF; } } + +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +/// Start address of the Read-Only (RO) range. +/// +/// # Safety +/// +/// - 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 } +} + +/// Size of the Read-Only (RO) range of the kernel binary. +/// +/// # Safety +/// +/// - 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 } +} + +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + +/// Return the 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, + } + } +} diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs index 31c6f9a6..578591de 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs @@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2; pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( memory_map::END_INCLUSIVE, [ - RangeDescriptor { + TranslationDescriptor { name: "Kernel code and RO data", - virtual_range: || { - // Using the linker script, we ensure that the RO area is consecutive and 64 KiB - // aligned, and we export the boundaries via symbols: - // - // [__ro_start, __ro_end) - extern "C" { - // The inclusive start of the read-only area, aka the address of the first - // byte of the area. - static __ro_start: usize; - - // The exclusive end of the read-only area, aka the address of the first - // byte _after_ the RO area. - static __ro_end: usize; - } - - unsafe { - // Notice the subtraction to turn the exclusive end into an inclusive end. - #[allow(clippy::range_minus_one)] - RangeInclusive::new( - &__ro_start as *const _ as usize, - &__ro_end as *const _ as usize - 1, - ) - } - }, - translation: Translation::Identity, + virtual_range: ro_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::CacheableDRAM, acc_perms: AccessPermissions::ReadOnly, execute_never: false, }, }, - RangeDescriptor { + TranslationDescriptor { name: "Device MMIO", - virtual_range: || { - RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) - }, - translation: Translation::Identity, + virtual_range: mmio_range_inclusive, + physical_range_translation: Translation::Identity, attribute_fields: AttributeFields { mem_attributes: MemAttributes::Device, acc_perms: AccessPermissions::ReadWrite, @@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout ], ); +//-------------------------------------------------------------------------------------------------- +// Private Code +//-------------------------------------------------------------------------------------------------- + +fn ro_range_inclusive() -> RangeInclusive { + // Notice the subtraction to turn the exclusive end into an inclusive end. + #[allow(clippy::range_minus_one)] + RangeInclusive::new(super::ro_start(), super::ro_end() - 1) +} + +fn mmio_range_inclusive() -> RangeInclusive { + RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) +} + //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- diff --git a/14_exceptions_part2_peripheral_IRQs/src/memory.rs b/14_exceptions_part2_peripheral_IRQs/src/memory.rs index 4a68a6d9..65d4b92b 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/memory.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/memory.rs @@ -12,7 +12,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/14_exceptions_part2_peripheral_IRQs/src/memory/mmu.rs b/14_exceptions_part2_peripheral_IRQs/src/memory/mmu.rs index 9a4885bd..39f3ef3c 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/memory/mmu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/memory/mmu.rs @@ -75,10 +75,10 @@ pub struct AttributeFields { /// Architecture agnostic descriptor for a memory range. #[allow(missing_docs)] -pub struct RangeDescriptor { +pub struct TranslationDescriptor { pub name: &'static str, pub virtual_range: fn() -> RangeInclusive, - pub translation: Translation, + pub physical_range_translation: Translation, pub attribute_fields: AttributeFields, } @@ -88,7 +88,7 @@ pub struct KernelVirtualLayout { max_virt_addr_inclusive: usize, /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. - inner: [RangeDescriptor; NUM_SPECIAL_RANGES], + inner: [TranslationDescriptor; NUM_SPECIAL_RANGES], } //-------------------------------------------------------------------------------------------------- @@ -105,8 +105,8 @@ impl Default for AttributeFields { } } -/// Human-readable output of a RangeDescriptor. -impl fmt::Display for RangeDescriptor { +/// Human-readable output of a TranslationDescriptor. +impl fmt::Display for TranslationDescriptor { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { // Call the function to which self.range points, and dereference the result, which causes // Rust to copy the value. @@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor { impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { /// Create a new instance. - pub const fn new(max: usize, layout: [RangeDescriptor; NUM_SPECIAL_RANGES]) -> Self { + pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self { Self { max_virt_addr_inclusive: max, inner: layout, } } - /// For a virtual address, find and return the output address and corresponding attributes. + /// For a virtual address, find and return the physical output address and corresponding + /// attributes. /// /// If the address is not found in `inner`, return an identity mapped default with normal /// cacheable DRAM attributes. @@ -175,7 +176,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } for i in self.inner.iter() { if (i.virtual_range)().contains(&virt_addr) { - let output_addr = match i.translation { + let output_addr = match i.physical_range_translation { Translation::Identity => virt_addr, Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), }; @@ -197,7 +198,7 @@ impl KernelVirtualLayout<{ NUM_SPECIAL_RANGES } } #[cfg(test)] - pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { + pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] { &self.inner } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs b/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs index 04cca287..a882dbe3 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //-------------------------------------------------------------------------------------------------- @@ -73,8 +53,8 @@ mod tests { fn bss_section_is_sane() { use core::mem; - let start = unsafe { bss_range().start } as *const _ as usize; - let end = unsafe { bss_range().end } as *const _ as usize; + 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); diff --git a/X1_JTAG_boot/jtag_boot_rpi3.img b/X1_JTAG_boot/jtag_boot_rpi3.img index 0ed207d9426b561c4a23bc01e8626268590a8a37..5408435157de05d7254423e5172595c4c23e0f88 100755 GIT binary patch delta 56 zcmX?Le!zT!3}fO(*>u*)J6L5Vx3KDPl>GlcU4cR2%H}JqJVJ~un;(i#XXNZ)u*)3s`kns{j9=KDmKaVe=JM9wEjZn;(i#XXM<&%E15vXErxV H+A{$F1$q&( diff --git a/X1_JTAG_boot/jtag_boot_rpi4.img b/X1_JTAG_boot/jtag_boot_rpi4.img index bfb9edad54c4213383394541fa1f8b39b946fec1..bfa5ecb0953656297a35680cc76aa76d77a0009b 100755 GIT binary patch delta 56 zcmdmBzQKHg3}f6z*=W|uYglC_SFq}El>GlcU4cR2%H|WS972p0n=gt_XXLD5 Range<*mut u64> { + unsafe { + Range { + start: &__bss_start as *const _ as *mut u64, + end: &__bss_end as *const _ as *mut u64, + } + } +} diff --git a/X1_JTAG_boot/src/memory.rs b/X1_JTAG_boot/src/memory.rs index 71dc0292..7af7f898 100644 --- a/X1_JTAG_boot/src/memory.rs +++ b/X1_JTAG_boot/src/memory.rs @@ -10,7 +10,7 @@ use core::ops::Range; // Public Code //-------------------------------------------------------------------------------------------------- -/// Zero out a memory region. +/// Zero out a memory range. /// /// # Safety /// diff --git a/X1_JTAG_boot/src/runtime_init.rs b/X1_JTAG_boot/src/runtime_init.rs index d517bd64..42c8f6af 100644 --- a/X1_JTAG_boot/src/runtime_init.rs +++ b/X1_JTAG_boot/src/runtime_init.rs @@ -4,32 +4,12 @@ //! Rust runtime initialization code. -use crate::memory; -use core::ops::Range; +use crate::{bsp, memory}; //-------------------------------------------------------------------------------------------------- // Private Code //-------------------------------------------------------------------------------------------------- -/// Return the range spanning the .bss section. -/// -/// # Safety -/// -/// - The symbol-provided addresses must be valid. -/// - The symbol-provided addresses must be usize aligned. -unsafe fn bss_range() -> Range<*mut usize> { - extern "C" { - // Boundaries of the .bss section, provided by linker script symbols. - static mut __bss_start: usize; - static mut __bss_end: usize; - } - - Range { - start: &mut __bss_start, - end: &mut __bss_end, - } -} - /// Zero out the .bss section. /// /// # Safety @@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> { /// - Must only be called pre `kernel_init()`. #[inline(always)] unsafe fn zero_bss() { - memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range()); } //--------------------------------------------------------------------------------------------------