From 22faff52298a7efa2982faabd80ca3d7b04ffc1f Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Tue, 29 Sep 2020 21:43:31 +0200 Subject: [PATCH] Various finetunings --- 03_hacky_hello_world/README.md | 8 +- 03_hacky_hello_world/src/print.rs | 6 +- 04_zero_overhead_abstraction/README.md | 20 +++- .../src/_arch/aarch64/cpu.rs | 2 +- .../src/bsp/raspberrypi/memory.rs | 13 ++- 04_zero_overhead_abstraction/src/print.rs | 6 +- 05_safe_globals/src/_arch/aarch64/cpu.rs | 2 +- 05_safe_globals/src/bsp/raspberrypi/memory.rs | 13 ++- 05_safe_globals/src/print.rs | 6 +- 06_drivers_gpio_uart/README.md | 68 ++++++------- 06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs | 2 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- 06_drivers_gpio_uart/src/driver.rs | 9 +- 06_drivers_gpio_uart/src/main.rs | 4 +- 06_drivers_gpio_uart/src/print.rs | 6 +- 07_uart_chainloader/README.md | 64 +++++++++++-- 07_uart_chainloader/src/_arch/aarch64/cpu.rs | 2 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 38 +++++--- 07_uart_chainloader/src/driver.rs | 9 +- 07_uart_chainloader/src/main.rs | 6 +- 07_uart_chainloader/src/print.rs | 6 +- 07_uart_chainloader/src/relocate.rs | 2 +- 08_timestamps/README.md | 74 +++++++++++---- 08_timestamps/src/_arch/aarch64/cpu.rs | 2 +- 08_timestamps/src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- 08_timestamps/src/bsp/device_driver/common.rs | 21 +++-- 08_timestamps/src/bsp/raspberrypi/driver.rs | 4 +- 08_timestamps/src/bsp/raspberrypi/memory.rs | 11 ++- 08_timestamps/src/driver.rs | 9 +- 08_timestamps/src/main.rs | 4 +- 08_timestamps/src/print.rs | 6 +- 09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs | 2 +- 09_hw_debug_JTAG/src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- 09_hw_debug_JTAG/src/driver.rs | 9 +- 09_hw_debug_JTAG/src/main.rs | 4 +- 09_hw_debug_JTAG/src/print.rs | 6 +- 10_privilege_level/README.md | 4 +- 10_privilege_level/src/_arch/aarch64/cpu.rs | 2 +- 10_privilege_level/src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- 10_privilege_level/src/driver.rs | 9 +- 10_privilege_level/src/main.rs | 4 +- 10_privilege_level/src/print.rs | 6 +- 11_virtual_memory/README.md | 16 ++-- 11_virtual_memory/src/_arch/aarch64/cpu.rs | 2 +- .../src/_arch/aarch64/memory/mmu.rs | 4 +- 11_virtual_memory/src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- 11_virtual_memory/src/driver.rs | 9 +- 11_virtual_memory/src/main.rs | 4 +- 11_virtual_memory/src/print.rs | 6 +- 12_exceptions_part1_groundwork/README.md | 2 +- .../src/_arch/aarch64/cpu.rs | 2 +- .../src/_arch/aarch64/exception.rs | 2 +- .../src/_arch/aarch64/memory/mmu.rs | 4 +- .../src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- 12_exceptions_part1_groundwork/src/driver.rs | 9 +- 12_exceptions_part1_groundwork/src/main.rs | 4 +- 12_exceptions_part1_groundwork/src/print.rs | 6 +- 13_integrated_testing/README.md | 24 +---- .../src/_arch/aarch64/cpu.rs | 2 +- .../src/_arch/aarch64/exception.rs | 2 +- .../src/_arch/aarch64/memory/mmu.rs | 4 +- .../src/_arch/aarch64/time.rs | 6 +- 13_integrated_testing/src/bsp.rs | 28 ------ .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- .../src/bsp/raspberrypi/memory/mmu.rs | 20 +++- 13_integrated_testing/src/driver.rs | 9 +- 13_integrated_testing/src/main.rs | 4 +- 13_integrated_testing/src/print.rs | 6 +- 14_exceptions_part2_peripheral_IRQs/README.md | 89 +++++++++++------- .../src/_arch/aarch64/cpu.rs | 2 +- .../src/_arch/aarch64/exception.rs | 2 +- .../src/_arch/aarch64/memory/mmu.rs | 4 +- .../src/_arch/aarch64/time.rs | 6 +- .../src/bsp.rs | 28 ------ .../src/bsp/device_driver/arm/gicv2.rs | 4 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../bcm/bcm2xxx_interrupt_controller.rs | 4 +- .../peripheral_ic.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- .../src/bsp/device_driver/common.rs | 21 +++-- .../src/bsp/raspberrypi/driver.rs | 4 +- .../src/bsp/raspberrypi/memory.rs | 11 ++- .../src/bsp/raspberrypi/memory/mmu.rs | 20 +++- .../src/driver.rs | 9 +- .../src/exception/asynchronous.rs | 44 ++++----- .../src/main.rs | 4 +- .../src/panic_wait.rs | 4 +- .../src/print.rs | 6 +- X1_JTAG_boot/jtag_boot_rpi3.img | Bin 7104 -> 7136 bytes X1_JTAG_boot/jtag_boot_rpi4.img | Bin 7088 -> 7120 bytes X1_JTAG_boot/src/_arch/aarch64/cpu.rs | 2 +- X1_JTAG_boot/src/_arch/aarch64/time.rs | 6 +- .../src/bsp/device_driver/bcm/bcm2xxx_gpio.rs | 2 +- .../device_driver/bcm/bcm2xxx_pl011_uart.rs | 4 +- X1_JTAG_boot/src/bsp/device_driver/common.rs | 21 +++-- X1_JTAG_boot/src/bsp/raspberrypi/driver.rs | 4 +- X1_JTAG_boot/src/bsp/raspberrypi/memory.rs | 11 ++- X1_JTAG_boot/src/driver.rs | 9 +- X1_JTAG_boot/src/main.rs | 4 +- X1_JTAG_boot/src/print.rs | 6 +- 134 files changed, 718 insertions(+), 584 deletions(-) diff --git a/03_hacky_hello_world/README.md b/03_hacky_hello_world/README.md index 5b97c3fa..7871a119 100644 --- a/03_hacky_hello_world/README.md +++ b/03_hacky_hello_world/README.md @@ -197,7 +197,7 @@ diff -uNr 02_runtime_init/src/panic_wait.rs 03_hacky_hello_world/src/panic_wait. diff -uNr 02_runtime_init/src/print.rs 03_hacky_hello_world/src/print.rs --- 02_runtime_init/src/print.rs +++ 03_hacky_hello_world/src/print.rs -@@ -0,0 +1,42 @@ +@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter @@ -208,7 +208,7 @@ diff -uNr 02_runtime_init/src/print.rs 03_hacky_hello_world/src/print.rs +use core::fmt; + +//-------------------------------------------------------------------------------------------------- -+// Private Code ++// Public Code +//-------------------------------------------------------------------------------------------------- + +#[doc(hidden)] @@ -218,10 +218,6 @@ diff -uNr 02_runtime_init/src/print.rs 03_hacky_hello_world/src/print.rs + bsp::console::console().write_fmt(args).unwrap(); +} + -+//-------------------------------------------------------------------------------------------------- -+// Public Code -+//-------------------------------------------------------------------------------------------------- -+ +/// Prints without a newline. +/// +/// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/03_hacky_hello_world/src/print.rs b/03_hacky_hello_world/src/print.rs index 7763a0e9..77ebd8b4 100644 --- a/03_hacky_hello_world/src/print.rs +++ b/03_hacky_hello_world/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/04_zero_overhead_abstraction/README.md b/04_zero_overhead_abstraction/README.md index 73c33a04..2ada1662 100644 --- a/04_zero_overhead_abstraction/README.md +++ b/04_zero_overhead_abstraction/README.md @@ -84,7 +84,7 @@ diff -uNr 03_hacky_hello_world/src/_arch/aarch64/cpu.rs 04_zero_overhead_abstrac + + // Expect the boot core to start in EL2. + if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { -+ SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); ++ SP.set(bsp::memory::boot_core_stack_end() as u64); + runtime_init::runtime_init() + } else { + // If not core0, infinitely wait for events. @@ -157,20 +157,32 @@ diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi/cpu.rs 04_zero_overhead_abstr diff -uNr 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs --- 03_hacky_hello_world/src/bsp/raspberrypi/memory.rs +++ 04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs -@@ -17,6 +17,13 @@ +@@ -17,9 +17,25 @@ } //-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + -+/// The early boot core's stack address. -+pub const BOOT_CORE_STACK_START: usize = 0x80_000; ++/// The board's memory map. ++#[rustfmt::skip] ++pub(super) mod map { ++ pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++} + +//-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- ++/// Exclusive end address of the boot core's stack. ++#[inline(always)] ++pub fn boot_core_stack_end() -> usize { ++ map::BOOT_CORE_STACK_END ++} ++ + /// Return the range spanning the .bss section. + /// + /// # Safety 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 diff --git a/04_zero_overhead_abstraction/src/_arch/aarch64/cpu.rs b/04_zero_overhead_abstraction/src/_arch/aarch64/cpu.rs index 12780497..28156ec8 100644 --- a/04_zero_overhead_abstraction/src/_arch/aarch64/cpu.rs +++ b/04_zero_overhead_abstraction/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs index fb073898..cdd5ac99 100644 --- a/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs +++ b/04_zero_overhead_abstraction/src/bsp/raspberrypi/memory.rs @@ -20,13 +20,22 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; +/// The board's memory map. +#[rustfmt::skip] +pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; +} //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/04_zero_overhead_abstraction/src/print.rs b/04_zero_overhead_abstraction/src/print.rs index 7763a0e9..77ebd8b4 100644 --- a/04_zero_overhead_abstraction/src/print.rs +++ b/04_zero_overhead_abstraction/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/05_safe_globals/src/_arch/aarch64/cpu.rs b/05_safe_globals/src/_arch/aarch64/cpu.rs index 12780497..28156ec8 100644 --- a/05_safe_globals/src/_arch/aarch64/cpu.rs +++ b/05_safe_globals/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/05_safe_globals/src/bsp/raspberrypi/memory.rs b/05_safe_globals/src/bsp/raspberrypi/memory.rs index fb073898..cdd5ac99 100644 --- a/05_safe_globals/src/bsp/raspberrypi/memory.rs +++ b/05_safe_globals/src/bsp/raspberrypi/memory.rs @@ -20,13 +20,22 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; +/// The board's memory map. +#[rustfmt::skip] +pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; +} //-------------------------------------------------------------------------------------------------- // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/05_safe_globals/src/print.rs b/05_safe_globals/src/print.rs index 7763a0e9..77ebd8b4 100644 --- a/05_safe_globals/src/print.rs +++ b/05_safe_globals/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/06_drivers_gpio_uart/README.md b/06_drivers_gpio_uart/README.md index fa6db363..857fb7f9 100644 --- a/06_drivers_gpio_uart/README.md +++ b/06_drivers_gpio_uart/README.md @@ -268,7 +268,7 @@ diff -uNr 05_safe_globals/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs 06_drivers_g +use synchronization::interface::Mutex; + +impl driver::interface::DeviceDriver for GPIO { -+ fn compatible(&self) -> &str { ++ fn compatible(&self) -> &'static str { + "BCM GPIO" + } +} @@ -524,11 +524,11 @@ diff -uNr 05_safe_globals/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs 06_dri +use synchronization::interface::Mutex; + +impl driver::interface::DeviceDriver for PL011Uart { -+ fn compatible(&self) -> &str { ++ fn compatible(&self) -> &'static str { + "BCM PL011 UART" + } + -+ fn init(&self) -> Result<(), ()> { ++ unsafe fn init(&self) -> Result<(), &'static str> { + let mut r = &self.inner; + r.lock(|inner| inner.init()); + @@ -608,7 +608,7 @@ diff -uNr 05_safe_globals/src/bsp/device_driver/bcm.rs 06_drivers_gpio_uart/src/ diff -uNr 05_safe_globals/src/bsp/device_driver/common.rs 06_drivers_gpio_uart/src/bsp/device_driver/common.rs --- 05_safe_globals/src/bsp/device_driver/common.rs +++ 06_drivers_gpio_uart/src/bsp/device_driver/common.rs -@@ -0,0 +1,35 @@ +@@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2020 Andre Richter @@ -617,31 +617,34 @@ diff -uNr 05_safe_globals/src/bsp/device_driver/common.rs 06_drivers_gpio_uart/s + +use core::{marker::PhantomData, ops}; + ++//-------------------------------------------------------------------------------------------------- ++// Public Definitions ++//-------------------------------------------------------------------------------------------------- ++ +pub struct MMIODerefWrapper { -+ base_addr: usize, ++ start_addr: usize, + phantom: PhantomData, +} + ++//-------------------------------------------------------------------------------------------------- ++// Public Code ++//-------------------------------------------------------------------------------------------------- ++ +impl MMIODerefWrapper { + /// Create an instance. -+ pub const unsafe fn new(base_addr: usize) -> Self { ++ pub const unsafe fn new(start_addr: usize) -> Self { + Self { -+ base_addr, ++ start_addr, + phantom: PhantomData, + } + } -+ -+ /// Return a pointer to the associated MMIO register block. -+ fn ptr(&self) -> *const T { -+ self.base_addr as *const _ -+ } +} + +impl ops::Deref for MMIODerefWrapper { + type Target = T; + + fn deref(&self) -> &Self::Target { -+ unsafe { &*self.ptr() } ++ unsafe { &*(self.start_addr as *const _) } + } +} @@ -807,11 +810,11 @@ diff -uNr 05_safe_globals/src/bsp/raspberrypi/driver.rs 06_drivers_gpio_uart/src +use crate::driver; + +//-------------------------------------------------------------------------------------------------- -+// Public Definitions ++// Private Definitions +//-------------------------------------------------------------------------------------------------- + +/// Device Driver Manager type. -+pub struct BSPDriverManager { ++struct BSPDriverManager { + device_drivers: [&'static (dyn DeviceDriver + Sync); 2], +} + @@ -851,13 +854,13 @@ diff -uNr 05_safe_globals/src/bsp/raspberrypi/driver.rs 06_drivers_gpio_uart/src diff -uNr 05_safe_globals/src/bsp/raspberrypi/memory.rs 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs --- 05_safe_globals/src/bsp/raspberrypi/memory.rs +++ 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs -@@ -23,6 +23,33 @@ - /// The early boot core's stack address. - pub const BOOT_CORE_STACK_START: usize = 0x80_000; - -+/// The board's memory map. -+#[rustfmt::skip] -+pub(super) mod map { +@@ -23,7 +23,30 @@ + /// The board's memory map. + #[rustfmt::skip] + pub(super) mod map { +- pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++ pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++ + pub const GPIO_OFFSET: usize = 0x0020_0000; + pub const UART_OFFSET: usize = 0x0020_1000; + @@ -880,10 +883,8 @@ diff -uNr 05_safe_globals/src/bsp/raspberrypi/memory.rs 06_drivers_gpio_uart/src + pub const GPIO_BASE: usize = BASE + GPIO_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 @@ -980,7 +981,7 @@ diff -uNr 05_safe_globals/src/console.rs 06_drivers_gpio_uart/src/console.rs diff -uNr 05_safe_globals/src/driver.rs 06_drivers_gpio_uart/src/driver.rs --- 05_safe_globals/src/driver.rs +++ 06_drivers_gpio_uart/src/driver.rs -@@ -0,0 +1,41 @@ +@@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter @@ -993,14 +994,17 @@ diff -uNr 05_safe_globals/src/driver.rs 06_drivers_gpio_uart/src/driver.rs + +/// Driver interfaces. +pub mod interface { -+ + /// Device Driver functions. + pub trait DeviceDriver { + /// Return a compatibility string for identifying the driver. -+ fn compatible(&self) -> &str; ++ fn compatible(&self) -> &'static str; + + /// Called by the kernel to bring up the device. -+ fn init(&self) -> Result<(), ()> { ++ /// ++ /// # Safety ++ /// ++ /// - During init, drivers might do stuff with system-wide impact. ++ unsafe fn init(&self) -> Result<(), &'static str> { + Ok(()) + } + } @@ -1059,8 +1063,8 @@ diff -uNr 05_safe_globals/src/main.rs 06_drivers_gpio_uart/src/main.rs + use driver::interface::DriverManager; + + for i in bsp::driver::driver_manager().all_device_drivers().iter() { -+ if i.init().is_err() { -+ panic!("Error loading driver: {}", i.compatible()) ++ if let Err(x) = i.init() { ++ panic!("Error loading driver: {}: {}", i.compatible(), x); + } + } + bsp::driver::driver_manager().post_device_driver_init(); diff --git a/06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs b/06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs index b2d2cc44..f2d96678 100644 --- a/06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs +++ b/06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index e0a74caa..ccd1341e 100644 --- a/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/06_drivers_gpio_uart/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/06_drivers_gpio_uart/src/bsp/device_driver/common.rs b/06_drivers_gpio_uart/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/06_drivers_gpio_uart/src/bsp/device_driver/common.rs +++ b/06_drivers_gpio_uart/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/06_drivers_gpio_uart/src/bsp/raspberrypi/driver.rs b/06_drivers_gpio_uart/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/06_drivers_gpio_uart/src/bsp/raspberrypi/driver.rs +++ b/06_drivers_gpio_uart/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs index 90ff9b5b..ef9746af 100644 --- a/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs +++ b/06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs @@ -20,12 +20,11 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -54,6 +53,12 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/06_drivers_gpio_uart/src/driver.rs b/06_drivers_gpio_uart/src/driver.rs index c63b8301..e2875b87 100644 --- a/06_drivers_gpio_uart/src/driver.rs +++ b/06_drivers_gpio_uart/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/06_drivers_gpio_uart/src/main.rs b/06_drivers_gpio_uart/src/main.rs index d0f69d0f..d7306b07 100644 --- a/06_drivers_gpio_uart/src/main.rs +++ b/06_drivers_gpio_uart/src/main.rs @@ -130,8 +130,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/06_drivers_gpio_uart/src/print.rs b/06_drivers_gpio_uart/src/print.rs index 7763a0e9..77ebd8b4 100644 --- a/06_drivers_gpio_uart/src/print.rs +++ b/06_drivers_gpio_uart/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/07_uart_chainloader/README.md b/07_uart_chainloader/README.md index 6322134f..ab2b6f30 100644 --- a/07_uart_chainloader/README.md +++ b/07_uart_chainloader/README.md @@ -187,7 +187,7 @@ diff -uNr 06_drivers_gpio_uart/src/_arch/aarch64/cpu.rs 07_uart_chainloader/src/ // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); - runtime_init::runtime_init() + relocate::relocate_self::() } else { @@ -281,16 +281,60 @@ diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/link.ld 07_uart_chainloader/s diff -uNr 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs 07_uart_chainloader/src/bsp/raspberrypi/memory.rs --- 06_drivers_gpio_uart/src/bsp/raspberrypi/memory.rs +++ 07_uart_chainloader/src/bsp/raspberrypi/memory.rs -@@ -23,6 +23,9 @@ - /// The early boot core's stack address. - pub const BOOT_CORE_STACK_START: usize = 0x80_000; - -+/// The address on which the Raspberry firmware loads every binary by default. -+pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x80_000; -+ +@@ -23,19 +23,21 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { +- pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++ pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + +- pub const GPIO_OFFSET: usize = 0x0020_0000; +- pub const UART_OFFSET: usize = 0x0020_1000; ++ pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x8_0000; ++ ++ pub const GPIO_OFFSET: usize = 0x0020_0000; ++ pub const UART_OFFSET: usize = 0x0020_1000; + + /// Physical devices. + #[cfg(feature = "bsp_rpi3")] + pub mod mmio { + use super::*; + +- pub const BASE: usize = 0x3F00_0000; +- pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; +- pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; ++ pub const BASE: usize = 0x3F00_0000; ++ pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; ++ pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + } + + /// Physical devices. +@@ -43,9 +45,9 @@ + pub mod mmio { + use super::*; + +- pub const BASE: usize = 0xFE00_0000; +- pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; +- pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; ++ pub const BASE: usize = 0xFE00_0000; ++ pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; ++ pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + } + } + +@@ -59,6 +61,12 @@ + map::BOOT_CORE_STACK_END + } + ++/// The address on which the Raspberry firmware loads every binary by default. ++#[inline(always)] ++pub fn board_default_load_addr() -> usize { ++ map::BOARD_DEFAULT_LOAD_ADDRESS ++} ++ + /// Return the range spanning the .bss section. + /// + /// # Safety diff -uNr 06_drivers_gpio_uart/src/console.rs 07_uart_chainloader/src/console.rs --- 06_drivers_gpio_uart/src/console.rs @@ -379,7 +423,7 @@ diff -uNr 06_drivers_gpio_uart/src/main.rs 07_uart_chainloader/src/main.rs + console().write_char('O'); + console().write_char('K'); + -+ let kernel_addr: *mut u8 = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *mut u8; ++ let kernel_addr: *mut u8 = bsp::memory::board_default_load_addr() as *mut u8; + unsafe { + // Read the kernel byte by byte. + for i in 0..size { @@ -453,7 +497,7 @@ diff -uNr 06_drivers_gpio_uart/src/relocate.rs 07_uart_chainloader/src/relocate. + let mut reloc_dst_addr: *mut T = binary_start_addr as *mut T; + + // The address of where the previous firmware loaded us. -+ let mut src_addr: *const T = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *const _; ++ let mut src_addr: *const T = bsp::memory::board_default_load_addr() as *const _; + + // Copy the whole binary. + // diff --git a/07_uart_chainloader/src/_arch/aarch64/cpu.rs b/07_uart_chainloader/src/_arch/aarch64/cpu.rs index e2f79979..8eed0deb 100644 --- a/07_uart_chainloader/src/_arch/aarch64/cpu.rs +++ b/07_uart_chainloader/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); relocate::relocate_self::() } else { // If not core0, infinitely wait for events. diff --git a/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index ad2e82cf..b15efad5 100644 --- a/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/07_uart_chainloader/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/07_uart_chainloader/src/bsp/device_driver/common.rs b/07_uart_chainloader/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/07_uart_chainloader/src/bsp/device_driver/common.rs +++ b/07_uart_chainloader/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/07_uart_chainloader/src/bsp/raspberrypi/driver.rs b/07_uart_chainloader/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/07_uart_chainloader/src/bsp/raspberrypi/driver.rs +++ b/07_uart_chainloader/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs index 08b9034e..826fd8cc 100644 --- a/07_uart_chainloader/src/bsp/raspberrypi/memory.rs +++ b/07_uart_chainloader/src/bsp/raspberrypi/memory.rs @@ -20,26 +20,24 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - -/// The address on which the Raspberry firmware loads every binary by default. -pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { - pub const GPIO_OFFSET: usize = 0x0020_0000; - pub const UART_OFFSET: usize = 0x0020_1000; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + + pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x8_0000; + + pub const GPIO_OFFSET: usize = 0x0020_0000; + pub const UART_OFFSET: usize = 0x0020_1000; /// Physical devices. #[cfg(feature = "bsp_rpi3")] pub mod mmio { use super::*; - pub const BASE: usize = 0x3F00_0000; - pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; - pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + pub const BASE: usize = 0x3F00_0000; + pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; + pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } /// Physical devices. @@ -47,9 +45,9 @@ pub(super) mod map { pub mod mmio { use super::*; - pub const BASE: usize = 0xFE00_0000; - pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; - pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + pub const BASE: usize = 0xFE00_0000; + pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; + pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; } } @@ -57,6 +55,18 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + +/// The address on which the Raspberry firmware loads every binary by default. +#[inline(always)] +pub fn board_default_load_addr() -> usize { + map::BOARD_DEFAULT_LOAD_ADDRESS +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/07_uart_chainloader/src/driver.rs b/07_uart_chainloader/src/driver.rs index c63b8301..e2875b87 100644 --- a/07_uart_chainloader/src/driver.rs +++ b/07_uart_chainloader/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/07_uart_chainloader/src/main.rs b/07_uart_chainloader/src/main.rs index 43f2c2ee..808e5c73 100644 --- a/07_uart_chainloader/src/main.rs +++ b/07_uart_chainloader/src/main.rs @@ -132,8 +132,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); @@ -177,7 +177,7 @@ fn kernel_main() -> ! { console().write_char('O'); console().write_char('K'); - let kernel_addr: *mut u8 = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *mut u8; + let kernel_addr: *mut u8 = bsp::memory::board_default_load_addr() as *mut u8; unsafe { // Read the kernel byte by byte. for i in 0..size { diff --git a/07_uart_chainloader/src/print.rs b/07_uart_chainloader/src/print.rs index 7763a0e9..77ebd8b4 100644 --- a/07_uart_chainloader/src/print.rs +++ b/07_uart_chainloader/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/07_uart_chainloader/src/relocate.rs b/07_uart_chainloader/src/relocate.rs index 8a47d986..58ce399b 100644 --- a/07_uart_chainloader/src/relocate.rs +++ b/07_uart_chainloader/src/relocate.rs @@ -31,7 +31,7 @@ pub unsafe fn relocate_self() -> ! { let mut reloc_dst_addr: *mut T = binary_start_addr as *mut T; // The address of where the previous firmware loaded us. - let mut src_addr: *const T = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *const _; + let mut src_addr: *const T = bsp::memory::board_default_load_addr() as *const _; // Copy the whole binary. // diff --git a/08_timestamps/README.md b/08_timestamps/README.md index 0cc78a84..4ddbce50 100644 --- a/08_timestamps/README.md +++ b/08_timestamps/README.md @@ -111,7 +111,7 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/cpu.rs 08_timestamps/src/_arch/a // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); - relocate::relocate_self::() + runtime_init::runtime_init() } else { @@ -121,7 +121,7 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/cpu.rs 08_timestamps/src/_arch/a diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/aarch64/time.rs --- 07_uart_chainloader/src/_arch/aarch64/time.rs +++ 08_timestamps/src/_arch/aarch64/time.rs -@@ -0,0 +1,101 @@ +@@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2020 Andre Richter @@ -138,12 +138,8 @@ diff -uNr 07_uart_chainloader/src/_arch/aarch64/time.rs 08_timestamps/src/_arch/ + +const NS_PER_S: u64 = 1_000_000_000; + -+//-------------------------------------------------------------------------------------------------- -+// Public Definitions -+//-------------------------------------------------------------------------------------------------- -+ +/// ARMv8 Generic Timer. -+pub struct GenericTimer; ++struct GenericTimer; + +//-------------------------------------------------------------------------------------------------- +// Global instances @@ -284,16 +280,60 @@ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/link.ld 08_timestamps/src/bsp/ diff -uNr 07_uart_chainloader/src/bsp/raspberrypi/memory.rs 08_timestamps/src/bsp/raspberrypi/memory.rs --- 07_uart_chainloader/src/bsp/raspberrypi/memory.rs +++ 08_timestamps/src/bsp/raspberrypi/memory.rs -@@ -23,9 +23,6 @@ - /// The early boot core's stack address. - pub const BOOT_CORE_STACK_START: usize = 0x80_000; - --/// The address on which the Raspberry firmware loads every binary by default. --pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x80_000; -- +@@ -23,21 +23,19 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { +- pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++ pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + +- pub const BOARD_DEFAULT_LOAD_ADDRESS: usize = 0x8_0000; +- +- pub const GPIO_OFFSET: usize = 0x0020_0000; +- pub const UART_OFFSET: usize = 0x0020_1000; ++ pub const GPIO_OFFSET: usize = 0x0020_0000; ++ pub const UART_OFFSET: usize = 0x0020_1000; + + /// Physical devices. + #[cfg(feature = "bsp_rpi3")] + pub mod mmio { + use super::*; + +- pub const BASE: usize = 0x3F00_0000; +- pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; +- pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; ++ pub const BASE: usize = 0x3F00_0000; ++ pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; ++ pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + } + + /// Physical devices. +@@ -45,9 +43,9 @@ + pub mod mmio { + use super::*; + +- pub const BASE: usize = 0xFE00_0000; +- pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; +- pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; ++ pub const BASE: usize = 0xFE00_0000; ++ pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; ++ pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; + } + } + +@@ -61,12 +59,6 @@ + map::BOOT_CORE_STACK_END + } + +-/// The address on which the Raspberry firmware loads every binary by default. +-#[inline(always)] +-pub fn board_default_load_addr() -> usize { +- map::BOARD_DEFAULT_LOAD_ADDRESS +-} +- + /// Return the range spanning the .bss section. + /// + /// # Safety diff -uNr 07_uart_chainloader/src/main.rs 08_timestamps/src/main.rs --- 07_uart_chainloader/src/main.rs @@ -371,7 +411,7 @@ diff -uNr 07_uart_chainloader/src/main.rs 08_timestamps/src/main.rs - console().write_char('O'); - console().write_char('K'); - -- let kernel_addr: *mut u8 = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *mut u8; +- let kernel_addr: *mut u8 = bsp::memory::board_default_load_addr() as *mut u8; - unsafe { - // Read the kernel byte by byte. - for i in 0..size { @@ -410,7 +450,7 @@ diff -uNr 07_uart_chainloader/src/main.rs 08_timestamps/src/main.rs diff -uNr 07_uart_chainloader/src/print.rs 08_timestamps/src/print.rs --- 07_uart_chainloader/src/print.rs +++ 08_timestamps/src/print.rs -@@ -40,3 +40,71 @@ +@@ -36,3 +36,71 @@ $crate::print::_print(format_args_nl!($($arg)*)); }) } @@ -520,7 +560,7 @@ diff -uNr 07_uart_chainloader/src/relocate.rs 08_timestamps/src/relocate.rs - let mut reloc_dst_addr: *mut T = binary_start_addr as *mut T; - - // The address of where the previous firmware loaded us. -- let mut src_addr: *const T = bsp::memory::BOARD_DEFAULT_LOAD_ADDRESS as *const _; +- let mut src_addr: *const T = bsp::memory::board_default_load_addr() as *const _; - - // Copy the whole binary. - // diff --git a/08_timestamps/src/_arch/aarch64/cpu.rs b/08_timestamps/src/_arch/aarch64/cpu.rs index b2d2cc44..f2d96678 100644 --- a/08_timestamps/src/_arch/aarch64/cpu.rs +++ b/08_timestamps/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/08_timestamps/src/_arch/aarch64/time.rs b/08_timestamps/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/08_timestamps/src/_arch/aarch64/time.rs +++ b/08_timestamps/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/08_timestamps/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/08_timestamps/src/bsp/device_driver/common.rs b/08_timestamps/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/08_timestamps/src/bsp/device_driver/common.rs +++ b/08_timestamps/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/08_timestamps/src/bsp/raspberrypi/driver.rs b/08_timestamps/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/08_timestamps/src/bsp/raspberrypi/driver.rs +++ b/08_timestamps/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/08_timestamps/src/bsp/raspberrypi/memory.rs b/08_timestamps/src/bsp/raspberrypi/memory.rs index 90ff9b5b..ef9746af 100644 --- a/08_timestamps/src/bsp/raspberrypi/memory.rs +++ b/08_timestamps/src/bsp/raspberrypi/memory.rs @@ -20,12 +20,11 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -54,6 +53,12 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/08_timestamps/src/driver.rs b/08_timestamps/src/driver.rs index c63b8301..e2875b87 100644 --- a/08_timestamps/src/driver.rs +++ b/08_timestamps/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/08_timestamps/src/main.rs b/08_timestamps/src/main.rs index 0a2705e2..1966593f 100644 --- a/08_timestamps/src/main.rs +++ b/08_timestamps/src/main.rs @@ -133,8 +133,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/08_timestamps/src/print.rs b/08_timestamps/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/08_timestamps/src/print.rs +++ b/08_timestamps/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs b/09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs index b2d2cc44..f2d96678 100644 --- a/09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs +++ b/09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/09_hw_debug_JTAG/src/_arch/aarch64/time.rs b/09_hw_debug_JTAG/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/09_hw_debug_JTAG/src/_arch/aarch64/time.rs +++ b/09_hw_debug_JTAG/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/09_hw_debug_JTAG/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/09_hw_debug_JTAG/src/bsp/device_driver/common.rs b/09_hw_debug_JTAG/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/09_hw_debug_JTAG/src/bsp/device_driver/common.rs +++ b/09_hw_debug_JTAG/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/09_hw_debug_JTAG/src/bsp/raspberrypi/driver.rs b/09_hw_debug_JTAG/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/09_hw_debug_JTAG/src/bsp/raspberrypi/driver.rs +++ b/09_hw_debug_JTAG/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs index 90ff9b5b..ef9746af 100644 --- a/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs +++ b/09_hw_debug_JTAG/src/bsp/raspberrypi/memory.rs @@ -20,12 +20,11 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -54,6 +53,12 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/09_hw_debug_JTAG/src/driver.rs b/09_hw_debug_JTAG/src/driver.rs index c63b8301..e2875b87 100644 --- a/09_hw_debug_JTAG/src/driver.rs +++ b/09_hw_debug_JTAG/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/09_hw_debug_JTAG/src/main.rs b/09_hw_debug_JTAG/src/main.rs index 0a2705e2..1966593f 100644 --- a/09_hw_debug_JTAG/src/main.rs +++ b/09_hw_debug_JTAG/src/main.rs @@ -133,8 +133,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/09_hw_debug_JTAG/src/print.rs b/09_hw_debug_JTAG/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/09_hw_debug_JTAG/src/print.rs +++ b/09_hw_debug_JTAG/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/10_privilege_level/README.md b/10_privilege_level/README.md index edac3ded..5515c944 100644 --- a/10_privilege_level/README.md +++ b/10_privilege_level/README.md @@ -233,7 +233,7 @@ diff -uNr 09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs 10_privilege_level/src/_arch - // Expect the boot core to start in EL2. - if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { -- SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); +- SP.set(bsp::memory::boot_core_stack_end() as u64); - runtime_init::runtime_init() + if (bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id()) + && (CurrentEL.get() == CurrentEL::EL::EL2.value) @@ -281,7 +281,7 @@ diff -uNr 09_hw_debug_JTAG/src/_arch/aarch64/cpu.rs 10_privilege_level/src/_arch + ELR_EL2.set(runtime_init::runtime_init as *const () as u64); + + // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. -+ SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); ++ SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); + + // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. + asm::eret() diff --git a/10_privilege_level/src/_arch/aarch64/cpu.rs b/10_privilege_level/src/_arch/aarch64/cpu.rs index 24250a80..b066da5e 100644 --- a/10_privilege_level/src/_arch/aarch64/cpu.rs +++ b/10_privilege_level/src/_arch/aarch64/cpu.rs @@ -68,7 +68,7 @@ unsafe fn el2_to_el1_transition() -> ! { ELR_EL2.set(runtime_init::runtime_init as *const () as u64); // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. - SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. asm::eret() diff --git a/10_privilege_level/src/_arch/aarch64/time.rs b/10_privilege_level/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/10_privilege_level/src/_arch/aarch64/time.rs +++ b/10_privilege_level/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/10_privilege_level/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/10_privilege_level/src/bsp/device_driver/common.rs b/10_privilege_level/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/10_privilege_level/src/bsp/device_driver/common.rs +++ b/10_privilege_level/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/10_privilege_level/src/bsp/raspberrypi/driver.rs b/10_privilege_level/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/10_privilege_level/src/bsp/raspberrypi/driver.rs +++ b/10_privilege_level/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/10_privilege_level/src/bsp/raspberrypi/memory.rs b/10_privilege_level/src/bsp/raspberrypi/memory.rs index 90ff9b5b..ef9746af 100644 --- a/10_privilege_level/src/bsp/raspberrypi/memory.rs +++ b/10_privilege_level/src/bsp/raspberrypi/memory.rs @@ -20,12 +20,11 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -54,6 +53,12 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/10_privilege_level/src/driver.rs b/10_privilege_level/src/driver.rs index c63b8301..e2875b87 100644 --- a/10_privilege_level/src/driver.rs +++ b/10_privilege_level/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/10_privilege_level/src/main.rs b/10_privilege_level/src/main.rs index eaef9305..84073ee6 100644 --- a/10_privilege_level/src/main.rs +++ b/10_privilege_level/src/main.rs @@ -134,8 +134,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/10_privilege_level/src/print.rs b/10_privilege_level/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/10_privilege_level/src/print.rs +++ b/10_privilege_level/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/11_virtual_memory/README.md b/11_virtual_memory/README.md index fed7cba0..7f7aab12 100644 --- a/11_virtual_memory/README.md +++ b/11_virtual_memory/README.md @@ -440,7 +440,7 @@ diff -uNr 10_privilege_level/src/_arch/aarch64/memory/mmu.rs 11_virtual_memory/s +/// +/// # Safety +/// -+/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. ++/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". +static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); + +static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -593,7 +593,7 @@ diff -uNr 10_privilege_level/src/_arch/aarch64/memory/mmu.rs 11_virtual_memory/s +// Public Code +//-------------------------------------------------------------------------------------------------- + -+/// Return a reference to the MMU. ++/// Return a reference to the MMU instance. +pub fn mmu() -> &'static impl memory::mmu::interface::MMU { + &MMU +} @@ -770,16 +770,16 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src static __bss_start: usize; static __bss_end: usize; } -@@ -26,6 +30,8 @@ +@@ -23,6 +27,8 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + - pub const GPIO_OFFSET: usize = 0x0020_0000; - pub const UART_OFFSET: usize = 0x0020_1000; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; -@@ -37,6 +43,7 @@ + pub const GPIO_OFFSET: usize = 0x0020_0000; +@@ -36,6 +42,7 @@ pub const BASE: usize = 0x3F00_0000; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; @@ -787,7 +787,7 @@ diff -uNr 10_privilege_level/src/bsp/raspberrypi/memory.rs 11_virtual_memory/src } /// Physical devices. -@@ -47,10 +54,35 @@ +@@ -46,10 +53,35 @@ pub const BASE: usize = 0xFE00_0000; pub const GPIO_BASE: usize = BASE + GPIO_OFFSET; pub const PL011_UART_BASE: usize = BASE + UART_OFFSET; @@ -882,7 +882,7 @@ diff -uNr 10_privilege_level/src/main.rs 11_virtual_memory/src/main.rs + } for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { + if let Err(x) = i.init() { @@ -154,6 +168,9 @@ info!("Booting on: {}", bsp::board_name()); diff --git a/11_virtual_memory/src/_arch/aarch64/cpu.rs b/11_virtual_memory/src/_arch/aarch64/cpu.rs index 24250a80..b066da5e 100644 --- a/11_virtual_memory/src/_arch/aarch64/cpu.rs +++ b/11_virtual_memory/src/_arch/aarch64/cpu.rs @@ -68,7 +68,7 @@ unsafe fn el2_to_el1_transition() -> ! { ELR_EL2.set(runtime_init::runtime_init as *const () as u64); // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. - SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. asm::eret() diff --git a/11_virtual_memory/src/_arch/aarch64/memory/mmu.rs b/11_virtual_memory/src/_arch/aarch64/memory/mmu.rs index dd94f714..26b755e2 100644 --- a/11_virtual_memory/src/_arch/aarch64/memory/mmu.rs +++ b/11_virtual_memory/src/_arch/aarch64/memory/mmu.rs @@ -137,7 +137,7 @@ struct MemoryManagementUnit; /// /// # Safety /// -/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -290,7 +290,7 @@ fn configure_translation_control() { // Public Code //-------------------------------------------------------------------------------------------------- -/// Return a reference to the MMU. +/// Return a reference to the MMU instance. pub fn mmu() -> &'static impl memory::mmu::interface::MMU { &MMU } diff --git a/11_virtual_memory/src/_arch/aarch64/time.rs b/11_virtual_memory/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/11_virtual_memory/src/_arch/aarch64/time.rs +++ b/11_virtual_memory/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/11_virtual_memory/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/11_virtual_memory/src/bsp/device_driver/common.rs b/11_virtual_memory/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/11_virtual_memory/src/bsp/device_driver/common.rs +++ b/11_virtual_memory/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/11_virtual_memory/src/bsp/raspberrypi/driver.rs b/11_virtual_memory/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/11_virtual_memory/src/bsp/raspberrypi/driver.rs +++ b/11_virtual_memory/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/11_virtual_memory/src/bsp/raspberrypi/memory.rs b/11_virtual_memory/src/bsp/raspberrypi/memory.rs index dab98a9e..8f0b0104 100644 --- a/11_virtual_memory/src/bsp/raspberrypi/memory.rs +++ b/11_virtual_memory/src/bsp/raspberrypi/memory.rs @@ -24,14 +24,13 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -86,6 +85,12 @@ fn ro_end() -> usize { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/11_virtual_memory/src/driver.rs b/11_virtual_memory/src/driver.rs index c63b8301..e2875b87 100644 --- a/11_virtual_memory/src/driver.rs +++ b/11_virtual_memory/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/11_virtual_memory/src/main.rs b/11_virtual_memory/src/main.rs index 6d28aa69..f3156773 100644 --- a/11_virtual_memory/src/main.rs +++ b/11_virtual_memory/src/main.rs @@ -148,8 +148,8 @@ unsafe fn kernel_init() -> ! { } for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/11_virtual_memory/src/print.rs b/11_virtual_memory/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/11_virtual_memory/src/print.rs +++ b/11_virtual_memory/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/12_exceptions_part1_groundwork/README.md b/12_exceptions_part1_groundwork/README.md index b4f997a3..9227c081 100644 --- a/12_exceptions_part1_groundwork/README.md +++ b/12_exceptions_part1_groundwork/README.md @@ -525,7 +525,7 @@ diff -uNr 11_virtual_memory/src/_arch/aarch64/exception.rs 12_exceptions_part1_g +// Private Code +//-------------------------------------------------------------------------------------------------- + -+/// Print verbose information about the exception and the panic. ++/// Prints verbose information about the exception and then panics. +fn default_exception_handler(e: &ExceptionContext) { + panic!( + "\n\nCPU Exception!\n\ diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/cpu.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/cpu.rs index 24250a80..b066da5e 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/cpu.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/cpu.rs @@ -68,7 +68,7 @@ unsafe fn el2_to_el1_transition() -> ! { ELR_EL2.set(runtime_init::runtime_init as *const () as u64); // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. - SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. asm::eret() diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs index 261275bb..6c3a75ea 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/exception.rs @@ -42,7 +42,7 @@ struct EsrEL1; // Private Code //-------------------------------------------------------------------------------------------------- -/// Print verbose information about the exception and the panic. +/// Prints verbose information about the exception and then panics. fn default_exception_handler(e: &ExceptionContext) { panic!( "\n\nCPU Exception!\n\ diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs index dd94f714..26b755e2 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/memory/mmu.rs @@ -137,7 +137,7 @@ struct MemoryManagementUnit; /// /// # Safety /// -/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -290,7 +290,7 @@ fn configure_translation_control() { // Public Code //-------------------------------------------------------------------------------------------------- -/// Return a reference to the MMU. +/// Return a reference to the MMU instance. pub fn mmu() -> &'static impl memory::mmu::interface::MMU { &MMU } diff --git a/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs b/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs +++ b/12_exceptions_part1_groundwork/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/12_exceptions_part1_groundwork/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/12_exceptions_part1_groundwork/src/bsp/device_driver/common.rs b/12_exceptions_part1_groundwork/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/12_exceptions_part1_groundwork/src/bsp/device_driver/common.rs +++ b/12_exceptions_part1_groundwork/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/driver.rs b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/driver.rs +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs index dab98a9e..8f0b0104 100644 --- a/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs +++ b/12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory.rs @@ -24,14 +24,13 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -86,6 +85,12 @@ fn ro_end() -> usize { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/12_exceptions_part1_groundwork/src/driver.rs b/12_exceptions_part1_groundwork/src/driver.rs index c63b8301..e2875b87 100644 --- a/12_exceptions_part1_groundwork/src/driver.rs +++ b/12_exceptions_part1_groundwork/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/12_exceptions_part1_groundwork/src/main.rs b/12_exceptions_part1_groundwork/src/main.rs index d9473f18..5094311d 100644 --- a/12_exceptions_part1_groundwork/src/main.rs +++ b/12_exceptions_part1_groundwork/src/main.rs @@ -151,8 +151,8 @@ unsafe fn kernel_init() -> ! { } for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/12_exceptions_part1_groundwork/src/print.rs b/12_exceptions_part1_groundwork/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/12_exceptions_part1_groundwork/src/print.rs +++ b/12_exceptions_part1_groundwork/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/13_integrated_testing/README.md b/13_integrated_testing/README.md index f87b210b..ebf8cb3c 100644 --- a/13_integrated_testing/README.md +++ b/13_integrated_testing/README.md @@ -1000,7 +1000,7 @@ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/console.rs 13_integ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs 13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs --- 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs +++ 13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs -@@ -71,3 +71,28 @@ +@@ -71,3 +71,46 @@ pub fn virt_mem_layout() -> &'static KernelVirtualLayout<{ NUM_MEM_RANGES }> { &LAYOUT } @@ -1014,7 +1014,7 @@ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs 13_in + use super::*; + use test_macros::kernel_test; + -+ /// Check 64 KiB alignment of the kernel's virtual memory layout sections. ++ /// Check alignment of the kernel's virtual memory layout sections. + #[kernel_test] + fn virt_mem_layout_sections_are_64KiB_aligned() { + const SIXTYFOUR_KIB: usize = 65536; @@ -1028,29 +1028,11 @@ diff -uNr 12_exceptions_part1_groundwork/src/bsp/raspberrypi/memory/mmu.rs 13_in + assert!(end >= start); + } + } -+} - -diff -uNr 12_exceptions_part1_groundwork/src/bsp.rs 13_integrated_testing/src/bsp.rs ---- 12_exceptions_part1_groundwork/src/bsp.rs -+++ 13_integrated_testing/src/bsp.rs -@@ -11,3 +11,31 @@ - - #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] - pub use raspberrypi::*; -+ -+//-------------------------------------------------------------------------------------------------- -+// Testing -+//-------------------------------------------------------------------------------------------------- -+ -+#[cfg(test)] -+mod tests { -+ use super::*; -+ use test_macros::kernel_test; + + /// Ensure the kernel's virtual memory layout is free of overlaps. + #[kernel_test] + fn virt_mem_layout_has_no_overlaps() { -+ let layout = memory::mmu::virt_mem_layout().inner(); ++ let layout = virt_mem_layout().inner(); + + for (i, first) in layout.iter().enumerate() { + for second in layout.iter().skip(i + 1) { diff --git a/13_integrated_testing/src/_arch/aarch64/cpu.rs b/13_integrated_testing/src/_arch/aarch64/cpu.rs index 1e1c3eec..355e0804 100644 --- a/13_integrated_testing/src/_arch/aarch64/cpu.rs +++ b/13_integrated_testing/src/_arch/aarch64/cpu.rs @@ -68,7 +68,7 @@ unsafe fn el2_to_el1_transition() -> ! { ELR_EL2.set(runtime_init::runtime_init as *const () as u64); // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. - SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. asm::eret() diff --git a/13_integrated_testing/src/_arch/aarch64/exception.rs b/13_integrated_testing/src/_arch/aarch64/exception.rs index 41bd4ca2..28ea4d41 100644 --- a/13_integrated_testing/src/_arch/aarch64/exception.rs +++ b/13_integrated_testing/src/_arch/aarch64/exception.rs @@ -42,7 +42,7 @@ struct EsrEL1; // Private Code //-------------------------------------------------------------------------------------------------- -/// Print verbose information about the exception and the panic. +/// Prints verbose information about the exception and then panics. fn default_exception_handler(e: &ExceptionContext) { panic!( "\n\nCPU Exception!\n\ diff --git a/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs b/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs index dd94f714..26b755e2 100644 --- a/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs +++ b/13_integrated_testing/src/_arch/aarch64/memory/mmu.rs @@ -137,7 +137,7 @@ struct MemoryManagementUnit; /// /// # Safety /// -/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -290,7 +290,7 @@ fn configure_translation_control() { // Public Code //-------------------------------------------------------------------------------------------------- -/// Return a reference to the MMU. +/// Return a reference to the MMU instance. pub fn mmu() -> &'static impl memory::mmu::interface::MMU { &MMU } diff --git a/13_integrated_testing/src/_arch/aarch64/time.rs b/13_integrated_testing/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/13_integrated_testing/src/_arch/aarch64/time.rs +++ b/13_integrated_testing/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/13_integrated_testing/src/bsp.rs b/13_integrated_testing/src/bsp.rs index 3dbbba8c..3a5657ad 100644 --- a/13_integrated_testing/src/bsp.rs +++ b/13_integrated_testing/src/bsp.rs @@ -11,31 +11,3 @@ mod raspberrypi; #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] pub use raspberrypi::*; - -//-------------------------------------------------------------------------------------------------- -// Testing -//-------------------------------------------------------------------------------------------------- - -#[cfg(test)] -mod tests { - use super::*; - use test_macros::kernel_test; - - /// Ensure the kernel's virtual memory layout is free of overlaps. - #[kernel_test] - fn virt_mem_layout_has_no_overlaps() { - let layout = memory::mmu::virt_mem_layout().inner(); - - for (i, first) in layout.iter().enumerate() { - for second in layout.iter().skip(i + 1) { - let first_range = first.virtual_range; - let second_range = second.virtual_range; - - assert!(!first_range().contains(second_range().start())); - assert!(!first_range().contains(second_range().end())); - assert!(!second_range().contains(first_range().start())); - assert!(!second_range().contains(first_range().end())); - } - } - } -} diff --git a/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/13_integrated_testing/src/bsp/device_driver/common.rs b/13_integrated_testing/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/13_integrated_testing/src/bsp/device_driver/common.rs +++ b/13_integrated_testing/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/13_integrated_testing/src/bsp/raspberrypi/driver.rs b/13_integrated_testing/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/driver.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/13_integrated_testing/src/bsp/raspberrypi/memory.rs b/13_integrated_testing/src/bsp/raspberrypi/memory.rs index dab98a9e..8f0b0104 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/memory.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/memory.rs @@ -24,14 +24,13 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -86,6 +85,12 @@ fn ro_end() -> usize { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs b/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs index 578591de..97130c60 100644 --- a/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs +++ b/13_integrated_testing/src/bsp/raspberrypi/memory/mmu.rs @@ -81,7 +81,7 @@ mod tests { use super::*; use test_macros::kernel_test; - /// Check 64 KiB alignment of the kernel's virtual memory layout sections. + /// Check alignment of the kernel's virtual memory layout sections. #[kernel_test] fn virt_mem_layout_sections_are_64KiB_aligned() { const SIXTYFOUR_KIB: usize = 65536; @@ -95,4 +95,22 @@ mod tests { assert!(end >= start); } } + + /// Ensure the kernel's virtual memory layout is free of overlaps. + #[kernel_test] + fn virt_mem_layout_has_no_overlaps() { + let layout = virt_mem_layout().inner(); + + for (i, first) in layout.iter().enumerate() { + for second in layout.iter().skip(i + 1) { + let first_range = first.virtual_range; + let second_range = second.virtual_range; + + assert!(!first_range().contains(second_range().start())); + assert!(!first_range().contains(second_range().end())); + assert!(!second_range().contains(first_range().start())); + assert!(!second_range().contains(first_range().end())); + } + } + } } diff --git a/13_integrated_testing/src/driver.rs b/13_integrated_testing/src/driver.rs index c63b8301..e2875b87 100644 --- a/13_integrated_testing/src/driver.rs +++ b/13_integrated_testing/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/13_integrated_testing/src/main.rs b/13_integrated_testing/src/main.rs index 56410284..25017205 100644 --- a/13_integrated_testing/src/main.rs +++ b/13_integrated_testing/src/main.rs @@ -35,8 +35,8 @@ unsafe fn kernel_init() -> ! { } for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/13_integrated_testing/src/print.rs b/13_integrated_testing/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/13_integrated_testing/src/print.rs +++ b/13_integrated_testing/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/14_exceptions_part2_peripheral_IRQs/README.md b/14_exceptions_part2_peripheral_IRQs/README.md index b1356ebb..00bbc7dc 100644 --- a/14_exceptions_part2_peripheral_IRQs/README.md +++ b/14_exceptions_part2_peripheral_IRQs/README.md @@ -1355,11 +1355,11 @@ diff -uNr 13_integrated_testing/src/bsp/device_driver/arm/gicv2.rs 14_exceptions +use synchronization::interface::ReadWriteEx; + +impl driver::interface::DeviceDriver for GICv2 { -+ fn compatible(&self) -> &str { ++ fn compatible(&self) -> &'static str { + "GICv2 (ARM Generic Interrupt Controller v2)" + } + -+ fn init(&self) -> Result<(), ()> { ++ unsafe fn init(&self) -> Result<(), &'static str> { + if cpu::smp::core_id::() == bsp::cpu::BOOT_CORE_ID { + self.gicd.boot_core_init(); + } @@ -1542,7 +1542,7 @@ diff -uNr 13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_interrupt_cont +// Public Definitions +//-------------------------------------------------------------------------------------------------- + -+/// Representation of the peripheral interrupt regsler. ++/// Representation of the peripheral interrupt controller. +pub struct PeripheralIC { + /// Access to write registers is guarded with a lock. + wo_registers: IRQSafeNullLock, @@ -1691,7 +1691,7 @@ diff -uNr 13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_interrupt_cont +pub type PeripheralIRQ = + exception::asynchronous::IRQNumber<{ InterruptController::MAX_PERIPHERAL_IRQ_NUMBER }>; + -+/// Used for the associated type of trait [`exception::asynchronous::interface::IRQManager`]. ++/// Used for the associated type of trait [`exception::asynchronous::interface::IRQManager`]. +#[derive(Copy, Clone)] +pub enum IRQNumber { + Local(LocalIRQ), @@ -1756,7 +1756,7 @@ diff -uNr 13_integrated_testing/src/bsp/device_driver/bcm/bcm2xxx_interrupt_cont +//------------------------------------------------------------------------------ + +impl driver::interface::DeviceDriver for InterruptController { -+ fn compatible(&self) -> &str { ++ fn compatible(&self) -> &'static str { + "BCM Interrupt Controller" + } +} @@ -2069,7 +2069,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/driver.rs 14_exceptions_part @@ -12,7 +12,7 @@ /// Device Driver Manager type. - pub struct BSPDriverManager { + struct BSPDriverManager { - device_drivers: [&'static (dyn DeviceDriver + Sync); 2], + device_drivers: [&'static (dyn DeviceDriver + Sync); 3], } @@ -2145,13 +2145,16 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/exception.rs 14_exceptions_p diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs --- 13_integrated_testing/src/bsp/raspberrypi/memory.rs +++ 14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs -@@ -30,20 +30,22 @@ +@@ -27,22 +27,24 @@ /// The board's memory map. #[rustfmt::skip] pub(super) mod map { - pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; +- pub const BOOT_CORE_STACK_END: usize = 0x8_0000; ++ pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + - pub const GPIO_OFFSET: usize = 0x0020_0000; - pub const UART_OFFSET: usize = 0x0020_1000; + pub const GPIO_OFFSET: usize = 0x0020_0000; @@ -2175,7 +2178,7 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi/memory.rs 14_exceptions_part } /// Physical devices. -@@ -51,10 +53,12 @@ +@@ -50,10 +52,12 @@ pub mod mmio { use super::*; @@ -2236,8 +2239,8 @@ diff -uNr 13_integrated_testing/src/bsp/raspberrypi.rs 14_exceptions_part2_perip diff -uNr 13_integrated_testing/src/driver.rs 14_exceptions_part2_peripheral_IRQs/src/driver.rs --- 13_integrated_testing/src/driver.rs +++ 14_exceptions_part2_peripheral_IRQs/src/driver.rs -@@ -20,6 +20,14 @@ - fn init(&self) -> Result<(), ()> { +@@ -23,6 +23,14 @@ + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } + @@ -2266,6 +2269,28 @@ diff -uNr 13_integrated_testing/src/exception/asynchronous.rs 14_exceptions_part +// Public Definitions +//-------------------------------------------------------------------------------------------------- + ++/// Interrupt descriptor. ++#[derive(Copy, Clone)] ++pub struct IRQDescriptor { ++ /// Descriptive name. ++ pub name: &'static str, ++ ++ /// Reference to handler trait object. ++ pub handler: &'static (dyn interface::IRQHandler + Sync), ++} ++ ++/// IRQContext token. ++/// ++/// An instance of this type indicates that the local core is currently executing in IRQ ++/// context, aka executing an interrupt vector or subcalls of it. ++/// ++/// Concept and implementation derived from the `CriticalSection` introduced in ++/// https://github.com/rust-embedded/bare-metal ++#[derive(Clone, Copy)] ++pub struct IRQContext<'irq_context> { ++ _0: PhantomData<&'irq_context ()>, ++} ++ +/// Asynchronous exception handling interfaces. +pub mod interface { + @@ -2311,28 +2336,6 @@ diff -uNr 13_integrated_testing/src/exception/asynchronous.rs 14_exceptions_part + } +} + -+/// Interrupt descriptor. -+#[derive(Copy, Clone)] -+pub struct IRQDescriptor { -+ /// Descriptive name. -+ pub name: &'static str, -+ -+ /// Reference to handler trait object. -+ pub handler: &'static (dyn interface::IRQHandler + Sync), -+} -+ -+/// IRQContext token. -+/// -+/// An instance of this type indicates that the local core is currently executing in IRQ -+/// context, aka executing an interrupt vector or subcalls of it. -+/// -+/// Concept and implementation derived from the `CriticalSection` introduced in -+/// https://github.com/rust-embedded/bare-metal -+#[derive(Clone, Copy)] -+pub struct IRQContext<'irq_context> { -+ _0: PhantomData<&'irq_context ()>, -+} -+ +/// A wrapper type for IRQ numbers with integrated range sanity check. +#[derive(Copy, Clone)] +pub struct IRQNumber(usize); @@ -2505,6 +2508,28 @@ diff -uNr 13_integrated_testing/src/main.rs 14_exceptions_part2_peripheral_IRQs/ + cpu::wait_forever(); } +diff -uNr 13_integrated_testing/src/panic_wait.rs 14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs +--- 13_integrated_testing/src/panic_wait.rs ++++ 14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs +@@ -4,7 +4,7 @@ + + //! A panic handler that infinitely waits. + +-use crate::{bsp, cpu}; ++use crate::{bsp, cpu, exception}; + use core::{fmt, panic::PanicInfo}; + + //-------------------------------------------------------------------------------------------------- +@@ -46,6 +46,8 @@ + + #[panic_handler] + fn panic(info: &PanicInfo) -> ! { ++ unsafe { exception::asynchronous::local_irq_mask() }; ++ + if let Some(args) = info.message() { + panic_println!("\nKernel panic: {}", args); + } else { + diff -uNr 13_integrated_testing/src/state.rs 14_exceptions_part2_peripheral_IRQs/src/state.rs --- 13_integrated_testing/src/state.rs +++ 14_exceptions_part2_peripheral_IRQs/src/state.rs diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/cpu.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/cpu.rs index 1e1c3eec..355e0804 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/cpu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/cpu.rs @@ -68,7 +68,7 @@ unsafe fn el2_to_el1_transition() -> ! { ELR_EL2.set(runtime_init::runtime_init as *const () as u64); // Set up SP_EL1 (stack pointer), which will be used by EL1 once we "return" to it. - SP_EL1.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP_EL1.set(bsp::memory::boot_core_stack_end() as u64); // Use `eret` to "return" to EL1. This results in execution of runtime_init() in EL1. asm::eret() diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs index 396618bf..c57784a4 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/exception.rs @@ -43,7 +43,7 @@ struct EsrEL1; // Private Code //-------------------------------------------------------------------------------------------------- -/// Print verbose information about the exception and the panic. +/// Prints verbose information about the exception and then panics. fn default_exception_handler(e: &ExceptionContext) { panic!( "\n\nCPU Exception!\n\ diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs index dd94f714..26b755e2 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/memory/mmu.rs @@ -137,7 +137,7 @@ struct MemoryManagementUnit; /// /// # Safety /// -/// - Supposed to land in `.bss`. Therefore, ensure that they boil down to all "0" entries. +/// - Supposed to land in `.bss`. Therefore, ensure that all initial member values boil down to "0". static mut TABLES: ArchTranslationTable = ArchTranslationTable::new(); static MMU: MemoryManagementUnit = MemoryManagementUnit; @@ -290,7 +290,7 @@ fn configure_translation_control() { // Public Code //-------------------------------------------------------------------------------------------------- -/// Return a reference to the MMU. +/// Return a reference to the MMU instance. pub fn mmu() -> &'static impl memory::mmu::interface::MMU { &MMU } diff --git a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp.rs index 3dbbba8c..3a5657ad 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp.rs @@ -11,31 +11,3 @@ mod raspberrypi; #[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))] pub use raspberrypi::*; - -//-------------------------------------------------------------------------------------------------- -// Testing -//-------------------------------------------------------------------------------------------------- - -#[cfg(test)] -mod tests { - use super::*; - use test_macros::kernel_test; - - /// Ensure the kernel's virtual memory layout is free of overlaps. - #[kernel_test] - fn virt_mem_layout_has_no_overlaps() { - let layout = memory::mmu::virt_mem_layout().inner(); - - for (i, first) in layout.iter().enumerate() { - for second in layout.iter().skip(i + 1) { - let first_range = first.virtual_range; - let second_range = second.virtual_range; - - assert!(!first_range().contains(second_range().start())); - assert!(!first_range().contains(second_range().end())); - assert!(!second_range().contains(first_range().start())); - assert!(!second_range().contains(first_range().end())); - } - } - } -} diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs index a2d23f01..18654e6f 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/arm/gicv2.rs @@ -134,11 +134,11 @@ impl GICv2 { use synchronization::interface::ReadWriteEx; impl driver::interface::DeviceDriver for GICv2 { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "GICv2 (ARM Generic Interrupt Controller v2)" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { if cpu::smp::core_id::() == bsp::cpu::BOOT_CORE_ID { self.gicd.boot_core_init(); } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index b3301f8d..5b9f6aee 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller.rs index 9b2f00a3..52708b2d 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller.rs @@ -26,7 +26,7 @@ pub type LocalIRQ = pub type PeripheralIRQ = exception::asynchronous::IRQNumber<{ InterruptController::MAX_PERIPHERAL_IRQ_NUMBER }>; -/// Used for the associated type of trait [`exception::asynchronous::interface::IRQManager`]. +/// Used for the associated type of trait [`exception::asynchronous::interface::IRQManager`]. #[derive(Copy, Clone)] pub enum IRQNumber { Local(LocalIRQ), @@ -91,7 +91,7 @@ impl InterruptController { //------------------------------------------------------------------------------ impl driver::interface::DeviceDriver for InterruptController { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM Interrupt Controller" } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs index f2b9fd39..000d959e 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_interrupt_controller/peripheral_ic.rs @@ -49,7 +49,7 @@ type HandlerTable = // Public Definitions //-------------------------------------------------------------------------------------------------- -/// Representation of the peripheral interrupt regsler. +/// Representation of the peripheral interrupt controller. pub struct PeripheralIC { /// Access to write registers is guarded with a lock. wo_registers: IRQSafeNullLock, diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index ac9c4e18..045d323f 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -331,11 +331,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/common.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/common.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/driver.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/driver.rs index b9e1e171..0b2348fb 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/driver.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 3], } diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs index 58abdb9e..b4338a51 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory.rs @@ -24,14 +24,13 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { pub const END_INCLUSIVE: usize = 0xFFFF_FFFF; + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -90,6 +89,12 @@ fn ro_end() -> usize { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs index 578591de..97130c60 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/bsp/raspberrypi/memory/mmu.rs @@ -81,7 +81,7 @@ mod tests { use super::*; use test_macros::kernel_test; - /// Check 64 KiB alignment of the kernel's virtual memory layout sections. + /// Check alignment of the kernel's virtual memory layout sections. #[kernel_test] fn virt_mem_layout_sections_are_64KiB_aligned() { const SIXTYFOUR_KIB: usize = 65536; @@ -95,4 +95,22 @@ mod tests { assert!(end >= start); } } + + /// Ensure the kernel's virtual memory layout is free of overlaps. + #[kernel_test] + fn virt_mem_layout_has_no_overlaps() { + let layout = virt_mem_layout().inner(); + + for (i, first) in layout.iter().enumerate() { + for second in layout.iter().skip(i + 1) { + let first_range = first.virtual_range; + let second_range = second.virtual_range; + + assert!(!first_range().contains(second_range().start())); + assert!(!first_range().contains(second_range().end())); + assert!(!second_range().contains(first_range().start())); + assert!(!second_range().contains(first_range().end())); + } + } + } } diff --git a/14_exceptions_part2_peripheral_IRQs/src/driver.rs b/14_exceptions_part2_peripheral_IRQs/src/driver.rs index 0e24b403..b7d44dad 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/driver.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } diff --git a/14_exceptions_part2_peripheral_IRQs/src/exception/asynchronous.rs b/14_exceptions_part2_peripheral_IRQs/src/exception/asynchronous.rs index 25a01736..1a3902a3 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/exception/asynchronous.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/exception/asynchronous.rs @@ -15,6 +15,28 @@ use core::{fmt, marker::PhantomData}; // Public Definitions //-------------------------------------------------------------------------------------------------- +/// Interrupt descriptor. +#[derive(Copy, Clone)] +pub struct IRQDescriptor { + /// Descriptive name. + pub name: &'static str, + + /// Reference to handler trait object. + pub handler: &'static (dyn interface::IRQHandler + Sync), +} + +/// IRQContext token. +/// +/// An instance of this type indicates that the local core is currently executing in IRQ +/// context, aka executing an interrupt vector or subcalls of it. +/// +/// Concept and implementation derived from the `CriticalSection` introduced in +/// https://github.com/rust-embedded/bare-metal +#[derive(Clone, Copy)] +pub struct IRQContext<'irq_context> { + _0: PhantomData<&'irq_context ()>, +} + /// Asynchronous exception handling interfaces. pub mod interface { @@ -60,28 +82,6 @@ pub mod interface { } } -/// Interrupt descriptor. -#[derive(Copy, Clone)] -pub struct IRQDescriptor { - /// Descriptive name. - pub name: &'static str, - - /// Reference to handler trait object. - pub handler: &'static (dyn interface::IRQHandler + Sync), -} - -/// IRQContext token. -/// -/// An instance of this type indicates that the local core is currently executing in IRQ -/// context, aka executing an interrupt vector or subcalls of it. -/// -/// Concept and implementation derived from the `CriticalSection` introduced in -/// https://github.com/rust-embedded/bare-metal -#[derive(Clone, Copy)] -pub struct IRQContext<'irq_context> { - _0: PhantomData<&'irq_context ()>, -} - /// A wrapper type for IRQ numbers with integrated range sanity check. #[derive(Copy, Clone)] pub struct IRQNumber(usize); diff --git a/14_exceptions_part2_peripheral_IRQs/src/main.rs b/14_exceptions_part2_peripheral_IRQs/src/main.rs index df81e718..73779613 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/main.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/main.rs @@ -35,8 +35,8 @@ unsafe fn kernel_init() -> ! { } for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs b/14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs index 218c0a88..52a89d17 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/panic_wait.rs @@ -4,7 +4,7 @@ //! A panic handler that infinitely waits. -use crate::{bsp, cpu}; +use crate::{bsp, cpu, exception}; use core::{fmt, panic::PanicInfo}; //-------------------------------------------------------------------------------------------------- @@ -46,6 +46,8 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + unsafe { exception::asynchronous::local_irq_mask() }; + if let Some(args) = info.message() { panic_println!("\nKernel panic: {}", args); } else { diff --git a/14_exceptions_part2_peripheral_IRQs/src/print.rs b/14_exceptions_part2_peripheral_IRQs/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/14_exceptions_part2_peripheral_IRQs/src/print.rs +++ b/14_exceptions_part2_peripheral_IRQs/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html diff --git a/X1_JTAG_boot/jtag_boot_rpi3.img b/X1_JTAG_boot/jtag_boot_rpi3.img index 5408435157de05d7254423e5172595c4c23e0f88..b577cbc43c961c7e73883d1cc62425c91c919970 100755 GIT binary patch delta 1132 zcmY*XO>7%g5T4ofde=#vYKi~WPVl-RICfE83n>=OAyz6xWU5A3k$M2BL`5aE5jH)Uw7joby3iOE9RDw9op%EZ3QfuB@FGxITc6VmJ znfcx~yH;=t=ZEm=E5lt3|KWp01gJSTfu)Ku_OlFZwVs!Ta1ac(CLh0{L9t__Rc^`2 zWqLv`>|YM#p&>He!_vm@GnyUZ^@~$!_8UiR$)V-D$5gxW66~5jx+V`-R?bO-Z)&3z zI}ibs!<+aBd=(1etbcVRI*^*zKI(-rBEb zZc|=~Rjg5#lCAO-jIzt#Ou<9u=5zTZ*$FV&oMM$6Z+keQpTHtl7R;2Zw8Qli zD)&@}nqaC`b1cJc617{`0cKtH!haS13W(rW-R|sj^o{ZWHtBC=BF;%a+Dv}oTtYUD z(CFhmgoY)&k7oQOEYd}PE?ga9J1TU#6(7HiY-?grlYa6igT)l5yst;up+2>cX+7M@ zD#gaBaOlCT0*&>1ta2ZZ9e)=Z83lHeru<`*bLeZ)DK&vDdQB}vs!`U@d+y=3%@=w4 zu_${hHAb82Q3=OrM9U8Fg$RUL`)SP5e>DR;s%We?FPkYs-hn}Yw;(r?R-h_k~J;r~1oqx|$H8J@QPh2(9 delta 1092 zcmY*XZ)g)|7=NBzF1gsIE;X0jHJ!;>+iT)xD60!w$C_5e(qW6Cpx@de%zrRO>*wV% z927R8FHbhwF}4;Q>^jhB5XrY_LGX)Pne*$i4KZm2DUNAA%=5k6<-=ZhdEe*vd;a|1 z-(4+J%`Erg{Eas)l%IK_hybP9-@r6b*k1y$>*XO&FYc`>tSZbtk|5hO(a6!9kjbY4 zLr}3%YZJHrnf94sUR%67z@7{7jk*xtcy&rN^Pj`+ngBD_R!DX1E|ph z?{Qh{WsMj#C;$8Sw+0_Id8;d?0j0#A6VCvOS%f3A3E_9kvZ8ilkKG*lnI;&yapNGn z#&g<31POY%L6(#~Cg znU+vH{sLaw*rsL8T%yO~TR2bMz7YhP@f-j>8Qa|1i-jaD zO7DsVoh3E8CjEj(%bx{qV{q+l#;pt6){aAYyd#5nlBRFq$Ic z&7^2JEyp9=909H|n2$sJC!i#N6t7~BR2ZnW^WU>zbosyg%>QuoPWs&+K2JY9dZ+7R zYt*S;Z{@$O0pCSQx9Yw830gObQM@K~3&l=clLktTB8(Jad;?%U$KbhBaq(x%vck?* zxxHMVti#o(c|t7buTaeYZN#`p+(b3TC0aiy$DKMwxt#yRi?cO#>X>oPSUGR|Ch5AZ zcaK7e%5WbiahB4wW|?yD20-Dl{~`QsV>d0UFoiXFKda#%a`vfOk~cH3HEPS25=l16 zXeNPVlU>c<@rG}VhS{w=(?-W=^XnpUH9VqZT52htE_UHZ$}M)H^0NOL z+hz9H9R;1k$n{pDI|dlzxUcO=oZ9&LgqmCg0 zDnr48_GLe72uRV@}UH8+i}tYaHk*ZKnOx{K-_x*rpI9~;EudN^=ScDW1QI*9M+DSavGqElYx zbk7F_Nmp<<85cSZL^lt>{ KdmP`4X8!}C&`CM~ delta 1113 zcmYLHUu;u#6h5c-w!Iy6SZI5DTco#auItP;7v?r+v@J#wG*Hqkfv3U3gAom38xK5a zdc~RWXAk@3ltkraKKO8#sKdsXJ=wVjSwav3Eb(o_2TL)NWhS}=yq^1KdXnbc^PPX+ z`TDyvI6pYE7e{YAzlpJR8L9{{pQ)>2^;ZxNB@kcNUhpLl4SHQVQt7HoCs(W`y!+2_ zzxih=U~Wq3xhQv3FLsEA6rHPFgpFAVMq)(}kSUl-q_72;Uzt1zoR7_cW%Xb3?YRn> zim8O%Tth;!8kEftz)Y@huV~?UZ)G&m$Vz4>80BUgm{tYNM@wxW9<}*QhvKXzR+*lP zP}M=d58MPshxmbBlSc-|pA+kOFgrsxKMy@Sd@uLmt?RjGZ{O?uq9x@_7cJsaBDb?Jd+S*o+D-Y$IHb+FJbGLljL zifjI-u}?^xJ6%W%nf(;#&YUs7QJ(hdY#p6Br*y&MmhE^|N;~>0+>=uldjtzIpJSg# z4E`I(skuFO0_eg@3Hk%x6LT($X)NQ_3juzjL>j+A5HE24zV^I z{zk?OH6xFGi#aMquhIK^zQh9Uj=su3trQ(bj;_SAsMEKxqx3X(BFv{kPn?Bei_>^q z#S?TnUg|SEj2Algu^01`b8O0sy%44-r2d8%XhT(#)tEbPa^iIFxrukrp6{8MwCkRz zv_EkaZ`wszrOSylo+C4n#aX(WNJr`kw~Zg6V?PsWy^$v#s(ENX6}4V$r*Tb|Up%0rLyYme~v5Q$X&U+{V{%K!iX diff --git a/X1_JTAG_boot/src/_arch/aarch64/cpu.rs b/X1_JTAG_boot/src/_arch/aarch64/cpu.rs index b2d2cc44..f2d96678 100644 --- a/X1_JTAG_boot/src/_arch/aarch64/cpu.rs +++ b/X1_JTAG_boot/src/_arch/aarch64/cpu.rs @@ -25,7 +25,7 @@ pub unsafe extern "C" fn _start() -> ! { // Expect the boot core to start in EL2. if bsp::cpu::BOOT_CORE_ID == cpu::smp::core_id() { - SP.set(bsp::memory::BOOT_CORE_STACK_START as u64); + SP.set(bsp::memory::boot_core_stack_end() as u64); runtime_init::runtime_init() } else { // If not core0, infinitely wait for events. diff --git a/X1_JTAG_boot/src/_arch/aarch64/time.rs b/X1_JTAG_boot/src/_arch/aarch64/time.rs index fb01ced1..d23864f3 100644 --- a/X1_JTAG_boot/src/_arch/aarch64/time.rs +++ b/X1_JTAG_boot/src/_arch/aarch64/time.rs @@ -14,12 +14,8 @@ use cortex_a::regs::*; const NS_PER_S: u64 = 1_000_000_000; -//-------------------------------------------------------------------------------------------------- -// Public Definitions -//-------------------------------------------------------------------------------------------------- - /// ARMv8 Generic Timer. -pub struct GenericTimer; +struct GenericTimer; //-------------------------------------------------------------------------------------------------- // Global instances diff --git a/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs b/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs index e448392a..77fd5d91 100644 --- a/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs +++ b/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_gpio.rs @@ -132,7 +132,7 @@ impl GPIO { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for GPIO { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM GPIO" } } diff --git a/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs b/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs index c9c5abed..4fa3b134 100644 --- a/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs +++ b/X1_JTAG_boot/src/bsp/device_driver/bcm/bcm2xxx_pl011_uart.rs @@ -245,11 +245,11 @@ impl PL011Uart { use synchronization::interface::Mutex; impl driver::interface::DeviceDriver for PL011Uart { - fn compatible(&self) -> &str { + fn compatible(&self) -> &'static str { "BCM PL011 UART" } - fn init(&self) -> Result<(), ()> { + unsafe fn init(&self) -> Result<(), &'static str> { let mut r = &self.inner; r.lock(|inner| inner.init()); diff --git a/X1_JTAG_boot/src/bsp/device_driver/common.rs b/X1_JTAG_boot/src/bsp/device_driver/common.rs index 8a83399a..56afb97a 100644 --- a/X1_JTAG_boot/src/bsp/device_driver/common.rs +++ b/X1_JTAG_boot/src/bsp/device_driver/common.rs @@ -6,30 +6,33 @@ use core::{marker::PhantomData, ops}; +//-------------------------------------------------------------------------------------------------- +// Public Definitions +//-------------------------------------------------------------------------------------------------- + pub struct MMIODerefWrapper { - base_addr: usize, + start_addr: usize, phantom: PhantomData, } +//-------------------------------------------------------------------------------------------------- +// Public Code +//-------------------------------------------------------------------------------------------------- + impl MMIODerefWrapper { /// Create an instance. - pub const unsafe fn new(base_addr: usize) -> Self { + pub const unsafe fn new(start_addr: usize) -> Self { Self { - base_addr, + start_addr, phantom: PhantomData, } } - - /// Return a pointer to the associated MMIO register block. - fn ptr(&self) -> *const T { - self.base_addr as *const _ - } } impl ops::Deref for MMIODerefWrapper { type Target = T; fn deref(&self) -> &Self::Target { - unsafe { &*self.ptr() } + unsafe { &*(self.start_addr as *const _) } } } diff --git a/X1_JTAG_boot/src/bsp/raspberrypi/driver.rs b/X1_JTAG_boot/src/bsp/raspberrypi/driver.rs index 86526dc0..fe24dd71 100644 --- a/X1_JTAG_boot/src/bsp/raspberrypi/driver.rs +++ b/X1_JTAG_boot/src/bsp/raspberrypi/driver.rs @@ -7,11 +7,11 @@ use crate::driver; //-------------------------------------------------------------------------------------------------- -// Public Definitions +// Private Definitions //-------------------------------------------------------------------------------------------------- /// Device Driver Manager type. -pub struct BSPDriverManager { +struct BSPDriverManager { device_drivers: [&'static (dyn DeviceDriver + Sync); 2], } diff --git a/X1_JTAG_boot/src/bsp/raspberrypi/memory.rs b/X1_JTAG_boot/src/bsp/raspberrypi/memory.rs index 90ff9b5b..ef9746af 100644 --- a/X1_JTAG_boot/src/bsp/raspberrypi/memory.rs +++ b/X1_JTAG_boot/src/bsp/raspberrypi/memory.rs @@ -20,12 +20,11 @@ extern "C" { // Public Definitions //-------------------------------------------------------------------------------------------------- -/// The early boot core's stack address. -pub const BOOT_CORE_STACK_START: usize = 0x80_000; - /// The board's memory map. #[rustfmt::skip] pub(super) mod map { + pub const BOOT_CORE_STACK_END: usize = 0x8_0000; + pub const GPIO_OFFSET: usize = 0x0020_0000; pub const UART_OFFSET: usize = 0x0020_1000; @@ -54,6 +53,12 @@ pub(super) mod map { // Public Code //-------------------------------------------------------------------------------------------------- +/// Exclusive end address of the boot core's stack. +#[inline(always)] +pub fn boot_core_stack_end() -> usize { + map::BOOT_CORE_STACK_END +} + /// Return the range spanning the .bss section. /// /// # Safety diff --git a/X1_JTAG_boot/src/driver.rs b/X1_JTAG_boot/src/driver.rs index c63b8301..e2875b87 100644 --- a/X1_JTAG_boot/src/driver.rs +++ b/X1_JTAG_boot/src/driver.rs @@ -10,14 +10,17 @@ /// Driver interfaces. pub mod interface { - /// Device Driver functions. pub trait DeviceDriver { /// Return a compatibility string for identifying the driver. - fn compatible(&self) -> &str; + fn compatible(&self) -> &'static str; /// Called by the kernel to bring up the device. - fn init(&self) -> Result<(), ()> { + /// + /// # Safety + /// + /// - During init, drivers might do stuff with system-wide impact. + unsafe fn init(&self) -> Result<(), &'static str> { Ok(()) } } diff --git a/X1_JTAG_boot/src/main.rs b/X1_JTAG_boot/src/main.rs index 2e0688e1..9d18b12c 100644 --- a/X1_JTAG_boot/src/main.rs +++ b/X1_JTAG_boot/src/main.rs @@ -133,8 +133,8 @@ unsafe fn kernel_init() -> ! { use driver::interface::DriverManager; for i in bsp::driver::driver_manager().all_device_drivers().iter() { - if i.init().is_err() { - panic!("Error loading driver: {}", i.compatible()) + if let Err(x) = i.init() { + panic!("Error loading driver: {}: {}", i.compatible(), x); } } bsp::driver::driver_manager().post_device_driver_init(); diff --git a/X1_JTAG_boot/src/print.rs b/X1_JTAG_boot/src/print.rs index cc303bfc..8b6f3f98 100644 --- a/X1_JTAG_boot/src/print.rs +++ b/X1_JTAG_boot/src/print.rs @@ -8,7 +8,7 @@ use crate::{bsp, console}; use core::fmt; //-------------------------------------------------------------------------------------------------- -// Private Code +// Public Code //-------------------------------------------------------------------------------------------------- #[doc(hidden)] @@ -18,10 +18,6 @@ pub fn _print(args: fmt::Arguments) { bsp::console::console().write_fmt(args).unwrap(); } -//-------------------------------------------------------------------------------------------------- -// Public Code -//-------------------------------------------------------------------------------------------------- - /// Prints without a newline. /// /// Carbon copy from https://doc.rust-lang.org/src/std/macros.rs.html