Move anything wrt linker symbols to bsp::memory

Also, some rewording of data types.
pull/84/head
Andre Richter 4 years ago
parent af0214f0f6
commit 37b9d1435e
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -74,6 +74,57 @@ diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/ra
/DISCARD/ : { *(.comment*) } /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 <andre.o.richter@gmail.com>
+
+//! 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 diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs
--- 01_wait_forever/src/main.rs --- 01_wait_forever/src/main.rs
+++ 02_runtime_init/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 +// Public Code
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------
+ +
+/// Zero out a memory region. +/// Zero out a memory range.
+/// +///
+/// # Safety +/// # 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 diff -uNr 01_wait_forever/src/runtime_init.rs 02_runtime_init/src/runtime_init.rs
--- 01_wait_forever/src/runtime_init.rs --- 01_wait_forever/src/runtime_init.rs
+++ 02_runtime_init/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 +// SPDX-License-Identifier: MIT OR Apache-2.0
+// +//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com> +// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
+ +
+//! Rust runtime initialization code. +//! Rust runtime initialization code.
+ +
+use crate::memory; +use crate::{bsp, memory};
+use core::ops::Range;
+ +
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------
+// Private Code +// 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. +/// Zero out the .bss section.
+/// +///
+/// # Safety +/// # 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()`. +/// - Must only be called pre `kernel_init()`.
+#[inline(always)] +#[inline(always)]
+unsafe fn zero_bss() { +unsafe fn zero_bss() {
+ memory::zero_volatile(bss_range()); + memory::zero_volatile(bsp::memory::bss_range());
+} +}
+ +
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------

@ -4,4 +4,4 @@
//! Top-level BSP file for the Raspberry Pi 3 and 4. //! Top-level BSP file for the Raspberry Pi 3 and 4.
// Coming soon. pub mod memory;

@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 diff -uNr 02_runtime_init/src/bsp/raspberrypi.rs 03_hacky_hello_world/src/bsp/raspberrypi.rs
--- 02_runtime_init/src/bsp/raspberrypi.rs --- 02_runtime_init/src/bsp/raspberrypi.rs
+++ 03_hacky_hello_world/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. //! Top-level BSP file for the Raspberry Pi 3 and 4.
-// Coming soon.
+pub mod console; +pub mod console;
pub mod memory;
diff -uNr 02_runtime_init/src/console.rs 03_hacky_hello_world/src/console.rs diff -uNr 02_runtime_init/src/console.rs 03_hacky_hello_world/src/console.rs
--- 02_runtime_init/src/console.rs --- 02_runtime_init/src/console.rs

@ -5,3 +5,4 @@
//! Top-level BSP file for the Raspberry Pi 3 and 4. //! Top-level BSP file for the Raspberry Pi 3 and 4.
pub mod console; pub mod console;
pub mod memory;

@ -0,0 +1,36 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
//! 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 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 --- 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs
+++ 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs +++ 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs
@@ -0,0 +1,12 @@ @@ -17,6 +17,13 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0 }
+//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com> //--------------------------------------------------------------------------------------------------
+
+//! BSP Memory Management.
+
+//--------------------------------------------------------------------------------------------------
+// Public Definitions +// Public Definitions
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------
+ +
+/// The early boot core's stack address. +/// The early boot core's stack address.
+pub const BOOT_CORE_STACK_START: usize = 0x80_000; +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 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 --- 03_hacky_hello_world/src/bsp/raspberrypi.rs
+++ 04_zero_overhead_abstraction/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. //! Top-level BSP file for the Raspberry Pi 3 and 4.
pub mod console; pub mod console;
+pub mod cpu; +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 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 --- 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 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 --- 03_hacky_hello_world/src/runtime_init.rs
+++ 04_zero_overhead_abstraction/src/runtime_init.rs +++ 04_zero_overhead_abstraction/src/runtime_init.rs
@@ -50,8 +50,7 @@ @@ -30,8 +30,7 @@
/// # Safety /// # Safety
/// ///
/// - Only a single core must be active and running this function. /// - Only a single core must be active and running this function.

@ -4,9 +4,40 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// The early boot core's stack address. /// The early boot core's stack address.
pub const BOOT_CORE_STACK_START: usize = 0x80_000; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -4,9 +4,40 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// The early boot core's stack address. /// The early boot core's stack address.
pub const BOOT_CORE_STACK_START: usize = 0x80_000; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 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 --- 05_safe_globals/src/bsp/raspberrypi/memory.rs
+++ 06_drivers_gpio_uart/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. /// The early boot core's stack address.
pub const BOOT_CORE_STACK_START: usize = 0x80_000; pub const BOOT_CORE_STACK_START: usize = 0x80_000;
+
+/// The board's memory map. +/// The board's memory map.
+#[rustfmt::skip] +#[rustfmt::skip]
+pub(super) mod map { +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; + 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 diff -uNr 05_safe_globals/src/bsp/raspberrypi.rs 06_drivers_gpio_uart/src/bsp/raspberrypi.rs
--- 05_safe_globals/src/bsp/raspberrypi.rs --- 05_safe_globals/src/bsp/raspberrypi.rs

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -37,3 +49,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 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 --- 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs
+++ 07_uart_chainloader/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. /// The early boot core's stack address.
pub const BOOT_CORE_STACK_START: usize = 0x80_000; 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 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 --- 06_drivers_gpio_uart/src/runtime_init.rs
+++ 07_uart_chainloader/src/runtime_init.rs +++ 07_uart_chainloader/src/runtime_init.rs
@@ -8,9 +8,43 @@ @@ -7,9 +7,43 @@
use core::ops::Range; use crate::{bsp, memory};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
+// Private Definitions +// 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 {} +impl RunTimeInit for Traitor {}
+ +
/// Return the range spanning the .bss section. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@@ -44,14 +78,7 @@ @@ -24,14 +58,7 @@
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -40,3 +52,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,8 +4,7 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Definitions // Private Definitions
@ -45,25 +44,6 @@ pub trait RunTimeInit {
impl RunTimeInit for Traitor {} 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -71,7 +51,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 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 --- 07_uart_chainloader/src/bsp/raspberrypi/memory.rs
+++ 08_timestamps/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. /// The early boot core's stack address.
pub const BOOT_CORE_STACK_START: usize = 0x80_000; 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 diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init.rs
--- 07_uart_chainloader/src/runtime_init.rs --- 07_uart_chainloader/src/runtime_init.rs
+++ 08_timestamps/src/runtime_init.rs +++ 08_timestamps/src/runtime_init.rs
@@ -8,43 +8,9 @@ @@ -7,43 +7,9 @@
use core::ops::Range; use crate::{bsp, memory};
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
-// Private Definitions -// Private Definitions
@ -584,10 +584,10 @@ diff -uNr 07_uart_chainloader/src/runtime_init.rs 08_timestamps/src/runtime_init
-impl RunTimeInit for Traitor {} -impl RunTimeInit for Traitor {}
- -
/// Return the range spanning the .bss section. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@@ -78,7 +44,14 @@ @@ -58,7 +24,14 @@
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -37,3 +49,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -37,3 +49,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -37,3 +49,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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: for composing a high-level data structure that describes the kernel's virtual memory layout:
`memory::mmu::KernelVirtualLayout`. `memory::mmu::KernelVirtualLayout`.
2. The `BSP` part: `src/bsp/raspberrypi/memory/mmu.rs` contains a static instance of 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()`. `bsp::memory::mmu::virt_mem_layout()`.
3. The `aarch64` part: `src/_arch/aarch64/memory/mmu.rs` contains the actual `MMU` driver. It picks 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. 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` ### Generic Kernel code: `memory/mmu.rs`
The descriptor types provided in this file are building blocks which help to describe attributes of 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 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 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: region:
```rust ```rust
RangeDescriptor { TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory::map::mmio::BASE, memory::map::mmio::END_INCLUSIVE) physical_range_translation: Translation::Identity,
},
translation: Translation::Identity,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, 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 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 the translation, which delivers the physical output address (the `usize` in the return-tuple). The
address, and returns the respective findings for the first entry that is a hit. If no entry is function scans for a descriptor that contains the queried address, and returns the respective
found, it returns default attributes for normal chacheable DRAM and the input address, hence telling findings for the first entry that is a hit. If no entry is found, it returns default attributes for
the `MMU` code that the requested address should be `identity mapped`. 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. 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 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 --- 10_privilege_level/src/bsp/raspberrypi/memory/mmu.rs
+++ 11_virtual_memory/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 +// SPDX-License-Identifier: MIT OR Apache-2.0
+// +//
+// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com> +// Copyright (c) 2018-2020 Andre Richter <andre.o.richter@gmail.com>
@ -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( +pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new(
+ memory_map::END_INCLUSIVE, + memory_map::END_INCLUSIVE,
+ [ + [
+ RangeDescriptor { + TranslationDescriptor {
+ name: "Kernel code and RO data", + name: "Kernel code and RO data",
+ virtual_range: || { + virtual_range: ro_range_inclusive,
+ // Using the linker script, we ensure that the RO area is consecutive and 64 KiB + physical_range_translation: Translation::Identity,
+ // 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,
+ attribute_fields: AttributeFields { + attribute_fields: AttributeFields {
+ mem_attributes: MemAttributes::CacheableDRAM, + mem_attributes: MemAttributes::CacheableDRAM,
+ acc_perms: AccessPermissions::ReadOnly, + acc_perms: AccessPermissions::ReadOnly,
+ execute_never: false, + execute_never: false,
+ }, + },
+ }, + },
+ RangeDescriptor { + TranslationDescriptor {
+ name: "Remapped Device MMIO", + name: "Remapped Device MMIO",
+ virtual_range: || { + virtual_range: remapped_mmio_range_inclusive,
+ // The last 64 KiB slot in the first 512 MiB + physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
+ RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
+ },
+ translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
+ attribute_fields: AttributeFields { + attribute_fields: AttributeFields {
+ mem_attributes: MemAttributes::Device, + mem_attributes: MemAttributes::Device,
+ acc_perms: AccessPermissions::ReadWrite, + acc_perms: AccessPermissions::ReadWrite,
+ execute_never: true, + execute_never: true,
+ }, + },
+ }, + },
+ RangeDescriptor { + TranslationDescriptor {
+ name: "Device MMIO", + name: "Device MMIO",
+ virtual_range: || { + virtual_range: mmio_range_inclusive,
+ RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) + physical_range_translation: Translation::Identity,
+ },
+ translation: Translation::Identity,
+ attribute_fields: AttributeFields { + attribute_fields: AttributeFields {
+ mem_attributes: MemAttributes::Device, + mem_attributes: MemAttributes::Device,
+ acc_perms: AccessPermissions::ReadWrite, + 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<usize> {
+ // 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<usize> {
+ // The last 64 KiB slot in the first 512 MiB
+ RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
+}
+
+fn mmio_range_inclusive() -> RangeInclusive<usize> {
+ RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE)
+}
+
+//--------------------------------------------------------------------------------------------------
+// Public Code +// Public Code
+//-------------------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------------------
+ +
@ -752,10 +742,19 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src
+pub mod mmu; +pub mod mmu;
+ +
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Public Definitions @@ -12,6 +14,8 @@
//--------------------------------------------------------------------------------------------------
@@ -14,6 +16,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. /// The board's memory map.
#[rustfmt::skip] #[rustfmt::skip]
pub(super) mod map { 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 GPIO_OFFSET: usize = 0x0020_0000;
pub const UART_OFFSET: usize = 0x0020_1000; pub const UART_OFFSET: usize = 0x0020_1000;
@@ -25,6 +29,7 @@ @@ -37,6 +43,7 @@
pub const BASE: usize = 0x3F00_0000; pub const BASE: usize = 0x3F00_0000;
pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET;
pub const PL011_UART_BASE: usize = BASE + UART_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. /// Physical devices.
@@ -35,5 +40,6 @@ @@ -47,10 +54,35 @@
pub const BASE: usize = 0xFE00_0000; pub const BASE: usize = 0xFE00_0000;
pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET;
pub const PL011_UART_BASE: usize = BASE + UART_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 diff -uNr 10_privilege_level/src/bsp.rs 11_virtual_memory/src/bsp.rs
--- 10_privilege_level/src/bsp.rs --- 10_privilege_level/src/bsp.rs
+++ 11_virtual_memory/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 diff -uNr 10_privilege_level/src/memory/mmu.rs 11_virtual_memory/src/memory/mmu.rs
--- 10_privilege_level/src/memory/mmu.rs --- 10_privilege_level/src/memory/mmu.rs
+++ 11_virtual_memory/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 +// SPDX-License-Identifier: MIT OR Apache-2.0
+// +//
+// Copyright (c) 2020 Andre Richter <andre.o.richter@gmail.com> +// Copyright (c) 2020 Andre Richter <andre.o.richter@gmail.com>
@ -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. +/// Architecture agnostic descriptor for a memory range.
+#[allow(missing_docs)] +#[allow(missing_docs)]
+pub struct RangeDescriptor { +pub struct TranslationDescriptor {
+ pub name: &'static str, + pub name: &'static str,
+ pub virtual_range: fn() -> RangeInclusive<usize>, + pub virtual_range: fn() -> RangeInclusive<usize>,
+ pub translation: Translation, + pub physical_range_translation: Translation,
+ pub attribute_fields: AttributeFields, + 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, + max_virt_addr_inclusive: usize,
+ +
+ /// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. + /// 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. +/// Human-readable output of a TranslationDescriptor.
+impl fmt::Display for RangeDescriptor { +impl fmt::Display for TranslationDescriptor {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ // Call the function to which self.range points, and dereference the result, which causes + // Call the function to which self.range points, and dereference the result, which causes
+ // Rust to copy the value. + // 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<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { +impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
+ /// Create a new instance. + /// 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 { + Self {
+ max_virt_addr_inclusive: max, + max_virt_addr_inclusive: max,
+ inner: layout, + 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 + /// If the address is not found in `inner`, return an identity mapped default with normal
+ /// cacheable DRAM attributes. + /// 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() { + for i in self.inner.iter() {
+ if (i.virtual_range)().contains(&virt_addr) { + 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::Identity => virt_addr,
+ Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), + Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
+ }; + };

@ -6,6 +6,20 @@
pub mod mmu; 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -43,3 +57,46 @@ pub(super) mod map {
pub const END_INCLUSIVE: usize = 0xFF84_FFFF; 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,
}
}
}

@ -21,58 +21,30 @@ const NUM_MEM_RANGES: usize = 3;
pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new(
memory_map::END_INCLUSIVE, memory_map::END_INCLUSIVE,
[ [
RangeDescriptor { TranslationDescriptor {
name: "Kernel code and RO data", name: "Kernel code and RO data",
virtual_range: || { virtual_range: ro_range_inclusive,
// Using the linker script, we ensure that the RO area is consecutive and 64 KiB physical_range_translation: Translation::Identity,
// 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,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::CacheableDRAM, mem_attributes: MemAttributes::CacheableDRAM,
acc_perms: AccessPermissions::ReadOnly, acc_perms: AccessPermissions::ReadOnly,
execute_never: false, execute_never: false,
}, },
}, },
RangeDescriptor { TranslationDescriptor {
name: "Remapped Device MMIO", name: "Remapped Device MMIO",
virtual_range: || { virtual_range: remapped_mmio_range_inclusive,
// The last 64 KiB slot in the first 512 MiB physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
},
translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, acc_perms: AccessPermissions::ReadWrite,
execute_never: true, execute_never: true,
}, },
}, },
RangeDescriptor { TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) physical_range_translation: Translation::Identity,
},
translation: Translation::Identity,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, acc_perms: AccessPermissions::ReadWrite,
@ -82,6 +54,25 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout
], ],
); );
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
fn ro_range_inclusive() -> RangeInclusive<usize> {
// 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<usize> {
// The last 64 KiB slot in the first 512 MiB
RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
}
fn mmio_range_inclusive() -> RangeInclusive<usize> {
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE)
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -12,7 +12,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -75,10 +75,10 @@ pub struct AttributeFields {
/// Architecture agnostic descriptor for a memory range. /// Architecture agnostic descriptor for a memory range.
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct RangeDescriptor { pub struct TranslationDescriptor {
pub name: &'static str, pub name: &'static str,
pub virtual_range: fn() -> RangeInclusive<usize>, pub virtual_range: fn() -> RangeInclusive<usize>,
pub translation: Translation, pub physical_range_translation: Translation,
pub attribute_fields: AttributeFields, pub attribute_fields: AttributeFields,
} }
@ -88,7 +88,7 @@ pub struct KernelVirtualLayout<const NUM_SPECIAL_RANGES: usize> {
max_virt_addr_inclusive: usize, max_virt_addr_inclusive: usize,
/// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. /// 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. /// Human-readable output of a TranslationDescriptor.
impl fmt::Display for RangeDescriptor { impl fmt::Display for TranslationDescriptor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Call the function to which self.range points, and dereference the result, which causes // Call the function to which self.range points, and dereference the result, which causes
// Rust to copy the value. // Rust to copy the value.
@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor {
impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
/// Create a new instance. /// 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 { Self {
max_virt_addr_inclusive: max, max_virt_addr_inclusive: max,
inner: layout, 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 /// If the address is not found in `inner`, return an identity mapped default with normal
/// cacheable DRAM attributes. /// cacheable DRAM attributes.
@ -175,7 +176,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
for i in self.inner.iter() { for i in self.inner.iter() {
if (i.virtual_range)().contains(&virt_addr) { 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::Identity => virt_addr,
Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
}; };

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -911,26 +911,35 @@ diff -uNr 11_virtual_memory/src/bsp/raspberrypi/memory/mmu.rs 12_exceptions_part
/// The virtual memory layout. /// The virtual memory layout.
/// ///
@@ -55,19 +55,6 @@ @@ -32,16 +32,6 @@
}, },
}, },
RangeDescriptor { TranslationDescriptor {
- name: "Remapped Device MMIO", - name: "Remapped Device MMIO",
- virtual_range: || { - virtual_range: remapped_mmio_range_inclusive,
- // The last 64 KiB slot in the first 512 MiB - physical_range_translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
- RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
- },
- translation: Translation::Offset(memory_map::mmio::BASE + 0x20_0000),
- attribute_fields: AttributeFields { - attribute_fields: AttributeFields {
- mem_attributes: MemAttributes::Device, - mem_attributes: MemAttributes::Device,
- acc_perms: AccessPermissions::ReadWrite, - acc_perms: AccessPermissions::ReadWrite,
- execute_never: true, - execute_never: true,
- }, - },
- }, - },
- RangeDescriptor { - TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_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<usize> {
- // The last 64 KiB slot in the first 512 MiB
- RangeInclusive::new(0x1FFF_0000, 0x1FFF_FFFF)
-}
-
fn mmio_range_inclusive() -> RangeInclusive<usize> {
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 diff -uNr 11_virtual_memory/src/bsp.rs 12_exceptions_part1_groundwork/src/bsp.rs
--- 11_virtual_memory/src/bsp.rs --- 11_virtual_memory/src/bsp.rs

@ -6,6 +6,20 @@
pub mod mmu; 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -43,3 +57,46 @@ pub(super) mod map {
pub const END_INCLUSIVE: usize = 0xFF84_FFFF; 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,
}
}
}

@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2;
pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new(
memory_map::END_INCLUSIVE, memory_map::END_INCLUSIVE,
[ [
RangeDescriptor { TranslationDescriptor {
name: "Kernel code and RO data", name: "Kernel code and RO data",
virtual_range: || { virtual_range: ro_range_inclusive,
// Using the linker script, we ensure that the RO area is consecutive and 64 KiB physical_range_translation: Translation::Identity,
// 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,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::CacheableDRAM, mem_attributes: MemAttributes::CacheableDRAM,
acc_perms: AccessPermissions::ReadOnly, acc_perms: AccessPermissions::ReadOnly,
execute_never: false, execute_never: false,
}, },
}, },
RangeDescriptor { TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) physical_range_translation: Translation::Identity,
},
translation: Translation::Identity,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, acc_perms: AccessPermissions::ReadWrite,
@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout
], ],
); );
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
fn ro_range_inclusive() -> RangeInclusive<usize> {
// 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<usize> {
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE)
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -12,7 +12,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -76,10 +76,10 @@ pub struct AttributeFields {
/// Architecture agnostic descriptor for a memory range. /// Architecture agnostic descriptor for a memory range.
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct RangeDescriptor { pub struct TranslationDescriptor {
pub name: &'static str, pub name: &'static str,
pub virtual_range: fn() -> RangeInclusive<usize>, pub virtual_range: fn() -> RangeInclusive<usize>,
pub translation: Translation, pub physical_range_translation: Translation,
pub attribute_fields: AttributeFields, pub attribute_fields: AttributeFields,
} }
@ -89,7 +89,7 @@ pub struct KernelVirtualLayout<const NUM_SPECIAL_RANGES: usize> {
max_virt_addr_inclusive: usize, max_virt_addr_inclusive: usize,
/// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. /// 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. /// Human-readable output of a TranslationDescriptor.
impl fmt::Display for RangeDescriptor { impl fmt::Display for TranslationDescriptor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Call the function to which self.range points, and dereference the result, which causes // Call the function to which self.range points, and dereference the result, which causes
// Rust to copy the value. // Rust to copy the value.
@ -155,14 +155,15 @@ impl fmt::Display for RangeDescriptor {
impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
/// Create a new instance. /// 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 { Self {
max_virt_addr_inclusive: max, max_virt_addr_inclusive: max,
inner: layout, 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 /// If the address is not found in `inner`, return an identity mapped default with normal
/// cacheable DRAM attributes. /// cacheable DRAM attributes.
@ -176,7 +177,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
for i in self.inner.iter() { for i in self.inner.iter() {
if (i.virtual_range)().contains(&virt_addr) { 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::Identity => virt_addr,
Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
}; };

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -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 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 --- 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs
+++ 13_integrated_testing/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 }> { pub fn virt_mem_layout() -> &'static KernelVirtualLayout<{ NUM_MEM_RANGES }> {
&LAYOUT &LAYOUT
} }
@ -1462,13 +1462,13 @@ diff -uNr 12_exceptions_part1_groundwork/src/memory/mmu.rs 13_integrated_testing
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub enum Translation { pub enum Translation {
Identity, Identity,
@@ -196,4 +195,9 @@ @@ -197,4 +196,9 @@
info!("{}", i); info!("{}", i);
} }
} }
+ +
+ #[cfg(test)] + #[cfg(test)]
+ pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { + pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] {
+ &self.inner + &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 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 --- 12_exceptions_part1_groundwork/src/runtime_init.rs
+++ 13_integrated_testing/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. /// - Only a single core must be active and running this function.
pub unsafe fn runtime_init() -> ! { 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() { + fn bss_section_is_sane() {
+ use core::mem; + use core::mem;
+ +
+ let start = unsafe { bss_range().start } as *const _ as usize; + let start = bsp::memory::bss_range().start as *const _ as usize;
+ let end = unsafe { bss_range().end } as *const _ as usize; + let end = bsp::memory::bss_range().end as *const _ as usize;
- crate::kernel_init() - crate::kernel_init()
+ assert_eq!(start modulo mem::size_of::<usize>(), 0); + assert_eq!(start modulo mem::size_of::<usize>(), 0);

@ -6,6 +6,20 @@
pub mod mmu; 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -43,3 +57,46 @@ pub(super) mod map {
pub const END_INCLUSIVE: usize = 0xFF84_FFFF; 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,
}
}
}

@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2;
pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new(
memory_map::END_INCLUSIVE, memory_map::END_INCLUSIVE,
[ [
RangeDescriptor { TranslationDescriptor {
name: "Kernel code and RO data", name: "Kernel code and RO data",
virtual_range: || { virtual_range: ro_range_inclusive,
// Using the linker script, we ensure that the RO area is consecutive and 64 KiB physical_range_translation: Translation::Identity,
// 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,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::CacheableDRAM, mem_attributes: MemAttributes::CacheableDRAM,
acc_perms: AccessPermissions::ReadOnly, acc_perms: AccessPermissions::ReadOnly,
execute_never: false, execute_never: false,
}, },
}, },
RangeDescriptor { TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) physical_range_translation: Translation::Identity,
},
translation: Translation::Identity,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, acc_perms: AccessPermissions::ReadWrite,
@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout
], ],
); );
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
fn ro_range_inclusive() -> RangeInclusive<usize> {
// 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<usize> {
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE)
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -12,7 +12,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -75,10 +75,10 @@ pub struct AttributeFields {
/// Architecture agnostic descriptor for a memory range. /// Architecture agnostic descriptor for a memory range.
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct RangeDescriptor { pub struct TranslationDescriptor {
pub name: &'static str, pub name: &'static str,
pub virtual_range: fn() -> RangeInclusive<usize>, pub virtual_range: fn() -> RangeInclusive<usize>,
pub translation: Translation, pub physical_range_translation: Translation,
pub attribute_fields: AttributeFields, pub attribute_fields: AttributeFields,
} }
@ -88,7 +88,7 @@ pub struct KernelVirtualLayout<const NUM_SPECIAL_RANGES: usize> {
max_virt_addr_inclusive: usize, max_virt_addr_inclusive: usize,
/// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. /// 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. /// Human-readable output of a TranslationDescriptor.
impl fmt::Display for RangeDescriptor { impl fmt::Display for TranslationDescriptor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Call the function to which self.range points, and dereference the result, which causes // Call the function to which self.range points, and dereference the result, which causes
// Rust to copy the value. // Rust to copy the value.
@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor {
impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
/// Create a new instance. /// 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 { Self {
max_virt_addr_inclusive: max, max_virt_addr_inclusive: max,
inner: layout, 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 /// If the address is not found in `inner`, return an identity mapped default with normal
/// cacheable DRAM attributes. /// cacheable DRAM attributes.
@ -175,7 +176,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
for i in self.inner.iter() { for i in self.inner.iter() {
if (i.virtual_range)().contains(&virt_addr) { 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::Identity => virt_addr,
Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
}; };
@ -197,7 +198,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
} }
#[cfg(test)] #[cfg(test)]
pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] {
&self.inner &self.inner
} }
} }

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { 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() { fn bss_section_is_sane() {
use core::mem; use core::mem;
let start = unsafe { bss_range().start } as *const _ as usize; let start = bsp::memory::bss_range().start as *const _ as usize;
let end = unsafe { bss_range().end } as *const _ as usize; let end = bsp::memory::bss_range().end as *const _ as usize;
assert_eq!(start % mem::size_of::<usize>(), 0); assert_eq!(start % mem::size_of::<usize>(), 0);
assert_eq!(end % mem::size_of::<usize>(), 0); assert_eq!(end % mem::size_of::<usize>(), 0);

@ -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 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 --- 13_integrated_testing/src/bsp/raspberrypi/memory.rs
+++ 14_exceptions_part2_peripheral_IRQs/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. /// The board's memory map.
#[rustfmt::skip] #[rustfmt::skip]
pub(super) mod map { pub(super) mod map {
@ -2175,7 +2175,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part
} }
/// Physical devices. /// Physical devices.
@@ -37,9 +39,11 @@ @@ -51,10 +53,12 @@
pub mod mmio { pub mod mmio {
use super::*; 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 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 --- 13_integrated_testing/src/bsp/raspberrypi.rs
+++ 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs +++ 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi.rs

@ -6,6 +6,20 @@
pub mod mmu; 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -47,3 +61,46 @@ pub(super) mod map {
pub const END_INCLUSIVE: usize = 0xFF84_FFFF; 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,
}
}
}

@ -21,45 +21,20 @@ const NUM_MEM_RANGES: usize = 2;
pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new( pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout::new(
memory_map::END_INCLUSIVE, memory_map::END_INCLUSIVE,
[ [
RangeDescriptor { TranslationDescriptor {
name: "Kernel code and RO data", name: "Kernel code and RO data",
virtual_range: || { virtual_range: ro_range_inclusive,
// Using the linker script, we ensure that the RO area is consecutive and 64 KiB physical_range_translation: Translation::Identity,
// 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,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::CacheableDRAM, mem_attributes: MemAttributes::CacheableDRAM,
acc_perms: AccessPermissions::ReadOnly, acc_perms: AccessPermissions::ReadOnly,
execute_never: false, execute_never: false,
}, },
}, },
RangeDescriptor { TranslationDescriptor {
name: "Device MMIO", name: "Device MMIO",
virtual_range: || { virtual_range: mmio_range_inclusive,
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE) physical_range_translation: Translation::Identity,
},
translation: Translation::Identity,
attribute_fields: AttributeFields { attribute_fields: AttributeFields {
mem_attributes: MemAttributes::Device, mem_attributes: MemAttributes::Device,
acc_perms: AccessPermissions::ReadWrite, acc_perms: AccessPermissions::ReadWrite,
@ -69,6 +44,20 @@ pub static LAYOUT: KernelVirtualLayout<{ NUM_MEM_RANGES }> = KernelVirtualLayout
], ],
); );
//--------------------------------------------------------------------------------------------------
// Private Code
//--------------------------------------------------------------------------------------------------
fn ro_range_inclusive() -> RangeInclusive<usize> {
// 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<usize> {
RangeInclusive::new(memory_map::mmio::BASE, memory_map::mmio::END_INCLUSIVE)
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

@ -12,7 +12,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -75,10 +75,10 @@ pub struct AttributeFields {
/// Architecture agnostic descriptor for a memory range. /// Architecture agnostic descriptor for a memory range.
#[allow(missing_docs)] #[allow(missing_docs)]
pub struct RangeDescriptor { pub struct TranslationDescriptor {
pub name: &'static str, pub name: &'static str,
pub virtual_range: fn() -> RangeInclusive<usize>, pub virtual_range: fn() -> RangeInclusive<usize>,
pub translation: Translation, pub physical_range_translation: Translation,
pub attribute_fields: AttributeFields, pub attribute_fields: AttributeFields,
} }
@ -88,7 +88,7 @@ pub struct KernelVirtualLayout<const NUM_SPECIAL_RANGES: usize> {
max_virt_addr_inclusive: usize, max_virt_addr_inclusive: usize,
/// Array of descriptors for non-standard (normal cacheable DRAM) memory regions. /// 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. /// Human-readable output of a TranslationDescriptor.
impl fmt::Display for RangeDescriptor { impl fmt::Display for TranslationDescriptor {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Call the function to which self.range points, and dereference the result, which causes // Call the function to which self.range points, and dereference the result, which causes
// Rust to copy the value. // Rust to copy the value.
@ -154,14 +154,15 @@ impl fmt::Display for RangeDescriptor {
impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> { impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
/// Create a new instance. /// 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 { Self {
max_virt_addr_inclusive: max, max_virt_addr_inclusive: max,
inner: layout, 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 /// If the address is not found in `inner`, return an identity mapped default with normal
/// cacheable DRAM attributes. /// cacheable DRAM attributes.
@ -175,7 +176,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
for i in self.inner.iter() { for i in self.inner.iter() {
if (i.virtual_range)().contains(&virt_addr) { 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::Identity => virt_addr,
Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()), Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
}; };
@ -197,7 +198,7 @@ impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }
} }
#[cfg(test)] #[cfg(test)]
pub fn inner(&self) -> &[RangeDescriptor; NUM_SPECIAL_RANGES] { pub fn inner(&self) -> &[TranslationDescriptor; NUM_SPECIAL_RANGES] {
&self.inner &self.inner
} }
} }

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { 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() { fn bss_section_is_sane() {
use core::mem; use core::mem;
let start = unsafe { bss_range().start } as *const _ as usize; let start = bsp::memory::bss_range().start as *const _ as usize;
let end = unsafe { bss_range().end } as *const _ as usize; let end = bsp::memory::bss_range().end as *const _ as usize;
assert_eq!(start % mem::size_of::<usize>(), 0); assert_eq!(start % mem::size_of::<usize>(), 0);
assert_eq!(end % mem::size_of::<usize>(), 0); assert_eq!(end % mem::size_of::<usize>(), 0);

Binary file not shown.

Binary file not shown.

@ -4,6 +4,18 @@
//! BSP Memory Management. //! 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 // Public Definitions
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -37,3 +49,22 @@ pub(super) mod map {
pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; 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,
}
}
}

@ -10,7 +10,7 @@ use core::ops::Range;
// Public Code // Public Code
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// Zero out a memory region. /// Zero out a memory range.
/// ///
/// # Safety /// # Safety
/// ///

@ -4,32 +4,12 @@
//! Rust runtime initialization code. //! Rust runtime initialization code.
use crate::memory; use crate::{bsp, memory};
use core::ops::Range;
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
// Private Code // 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. /// Zero out the .bss section.
/// ///
/// # Safety /// # Safety
@ -37,7 +17,7 @@ unsafe fn bss_range() -> Range<*mut usize> {
/// - Must only be called pre `kernel_init()`. /// - Must only be called pre `kernel_init()`.
#[inline(always)] #[inline(always)]
unsafe fn zero_bss() { unsafe fn zero_bss() {
memory::zero_volatile(bss_range()); memory::zero_volatile(bsp::memory::bss_range());
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

Loading…
Cancel
Save