Misc fixes/streamlining

pull/165/head
Andre Richter 2 years ago
parent fec4f9b6f2
commit 7aa99d52c0
No known key found for this signature in database
GPG Key ID: 2116C1AB102F615E

@ -331,7 +331,7 @@ Minipush 1.0
[ 0.811829] MMU online. Special regions:
[ 0.812306] 0x00080000 - 0x0008ffff | 64 KiB | C RO PX | Kernel code and RO data
[ 0.813324] 0x1fff0000 - 0x1fffffff | 64 KiB | Dev RW PXN | Remapped Device MMIO
[ 0.814310] 0x3f000000 - 0x4000ffff | 16 MiB | Dev RW PXN | Device MMIO
[ 0.814310] 0x3f000000 - 0x4000ffff | 17 MiB | Dev RW PXN | Device MMIO
[ 0.815198] Current privilege level: EL1
[ 0.815675] Exception handling state:
[ 0.816119] Debug: Masked
@ -1079,10 +1079,37 @@ diff -uNr 09_privilege_level/src/bsp.rs 10_virtual_mem_part1_identity_mapping/sr
#[cfg(any(feature = "bsp_rpi3", feature = "bsp_rpi4"))]
mod raspberrypi;
diff -uNr 09_privilege_level/src/common.rs 10_virtual_mem_part1_identity_mapping/src/common.rs
--- 09_privilege_level/src/common.rs
+++ 10_virtual_mem_part1_identity_mapping/src/common.rs
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
+
+//! General purpose code.
+
+/// Convert a size into human readable format.
+pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
+ const KIB: usize = 1024;
+ const MIB: usize = 1024 * 1024;
+ const GIB: usize = 1024 * 1024 * 1024;
+
+ if (size / GIB) > 0 {
+ (size.div_ceil(GIB), "GiB")
+ } else if (size / MIB) > 0 {
+ (size.div_ceil(MIB), "MiB")
+ } else if (size / KIB) > 0 {
+ (size.div_ceil(KIB), "KiB")
+ } else {
+ (size, "Byte")
+ }
+}
diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/src/main.rs
--- 09_privilege_level/src/main.rs
+++ 10_virtual_mem_part1_identity_mapping/src/main.rs
@@ -107,7 +107,9 @@
@@ -107,18 +107,23 @@
//! 2. Once finished with architectural setup, the arch code calls `kernel_init()`.
#![allow(clippy::upper_case_acronyms)]
@ -1090,9 +1117,15 @@ diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/s
#![feature(asm_const)]
+#![feature(core_intrinsics)]
#![feature(format_args_nl)]
+#![feature(int_roundings)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
@@ -119,6 +121,7 @@
#![no_main]
#![no_std]
mod bsp;
+mod common;
mod console;
mod cpu;
mod driver;
mod exception;
@ -1100,7 +1133,7 @@ diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/s
mod panic_wait;
mod print;
mod synchronization;
@@ -129,9 +132,17 @@
@@ -129,9 +134,17 @@
/// # Safety
///
/// - Only a single core must be active and running this function.
@ -1119,7 +1152,7 @@ diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/s
for i in bsp::driver::driver_manager().all_device_drivers().iter() {
if let Err(x) = i.init() {
@@ -147,7 +158,7 @@
@@ -147,7 +160,7 @@
/// The main function running after the early init.
fn kernel_main() -> ! {
@ -1128,7 +1161,7 @@ diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/s
use core::time::Duration;
use driver::interface::DriverManager;
use time::interface::TimeManager;
@@ -159,6 +170,9 @@
@@ -159,6 +172,9 @@
);
info!("Booting on: {}", bsp::board_name());
@ -1138,7 +1171,7 @@ diff -uNr 09_privilege_level/src/main.rs 10_virtual_mem_part1_identity_mapping/s
let (_, privilege_level) = exception::current_privilege_level();
info!("Current privilege level: {}", privilege_level);
@@ -182,6 +196,13 @@
@@ -182,6 +198,13 @@
info!("Timer test, spinning for 1 second");
time::time_manager().spin_for(Duration::from_secs(1));
@ -1175,7 +1208,7 @@ diff -uNr 09_privilege_level/src/memory/mmu/translation_table.rs 10_virtual_mem_
diff -uNr 09_privilege_level/src/memory/mmu.rs 10_virtual_mem_part1_identity_mapping/src/memory/mmu.rs
--- 09_privilege_level/src/memory/mmu.rs
+++ 10_virtual_mem_part1_identity_mapping/src/memory/mmu.rs
@@ -0,0 +1,264 @@
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
@ -1198,6 +1231,7 @@ diff -uNr 09_privilege_level/src/memory/mmu.rs 10_virtual_mem_part1_identity_map
+
+mod translation_table;
+
+use crate::common;
+use core::{fmt, ops::RangeInclusive};
+
+//--------------------------------------------------------------------------------------------------
@ -1357,19 +1391,7 @@ diff -uNr 09_privilege_level/src/memory/mmu.rs 10_virtual_mem_part1_identity_map
+ let end = *(self.virtual_range)().end();
+ let size = end - start + 1;
+
+ // log2(1024).
+ const KIB_RSHIFT: u32 = 10;
+
+ // log2(1024 * 1024).
+ const MIB_RSHIFT: u32 = 20;
+
+ let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
+ (size >> MIB_RSHIFT, "MiB")
+ } else if (size >> KIB_RSHIFT) > 0 {
+ (size >> KIB_RSHIFT, "KiB")
+ } else {
+ (size, "Byte")
+ };
+ let (size, unit) = common::size_human_readable_ceil(size);
+
+ let attr = match self.attribute_fields.mem_attributes {
+ MemAttributes::CacheableDRAM => "C",

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
//! General purpose code.
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -111,12 +111,14 @@
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(int_roundings)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
#![no_main]
#![no_std]
mod bsp;
mod common;
mod console;
mod cpu;
mod driver;

@ -20,6 +20,7 @@ mod arch_mmu;
mod translation_table;
use crate::common;
use core::{fmt, ops::RangeInclusive};
//--------------------------------------------------------------------------------------------------
@ -179,19 +180,7 @@ impl fmt::Display for TranslationDescriptor {
let end = *(self.virtual_range)().end();
let size = end - start + 1;
// log2(1024).
const KIB_RSHIFT: u32 = 10;
// log2(1024 * 1024).
const MIB_RSHIFT: u32 = 20;
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match self.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",

@ -421,7 +421,7 @@ Minipush 1.0
[ 0.798530] Booting on: Raspberry Pi 3
[ 0.798985] MMU online. Special regions:
[ 0.799462] 0x00080000 - 0x0008ffff | 64 KiB | C RO PX | Kernel code and RO data
[ 0.800480] 0x3f000000 - 0x4000ffff | 16 MiB | Dev RW PXN | Device MMIO
[ 0.800480] 0x3f000000 - 0x4000ffff | 17 MiB | Dev RW PXN | Device MMIO
[ 0.801369] Current privilege level: EL1
[ 0.801845] Exception handling state:
[ 0.802290] Debug: Masked
@ -1024,7 +1024,7 @@ diff -uNr 10_virtual_mem_part1_identity_mapping/src/exception.rs 11_exceptions_p
diff -uNr 10_virtual_mem_part1_identity_mapping/src/main.rs 11_exceptions_part1_groundwork/src/main.rs
--- 10_virtual_mem_part1_identity_mapping/src/main.rs
+++ 11_exceptions_part1_groundwork/src/main.rs
@@ -140,6 +140,8 @@
@@ -142,6 +142,8 @@
use driver::interface::DriverManager;
use memory::mmu::interface::MMU;
@ -1033,7 +1033,7 @@ diff -uNr 10_virtual_mem_part1_identity_mapping/src/main.rs 11_exceptions_part1_
if let Err(string) = memory::mmu::mmu().enable_mmu_and_caching() {
panic!("MMU: {}", string);
}
@@ -158,7 +160,7 @@
@@ -160,7 +162,7 @@
/// The main function running after the early init.
fn kernel_main() -> ! {
@ -1042,7 +1042,7 @@ diff -uNr 10_virtual_mem_part1_identity_mapping/src/main.rs 11_exceptions_part1_
use core::time::Duration;
use driver::interface::DriverManager;
use time::interface::TimeManager;
@@ -196,13 +198,28 @@
@@ -198,13 +200,28 @@
info!("Timer test, spinning for 1 second");
time::time_manager().spin_for(Duration::from_secs(1));

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
//! General purpose code.
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -111,12 +111,14 @@
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(int_roundings)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
#![no_main]
#![no_std]
mod bsp;
mod common;
mod console;
mod cpu;
mod driver;

@ -20,6 +20,7 @@ mod arch_mmu;
mod translation_table;
use crate::common;
use core::{fmt, ops::RangeInclusive};
//--------------------------------------------------------------------------------------------------
@ -179,19 +180,7 @@ impl fmt::Display for TranslationDescriptor {
let end = *(self.virtual_range)().end();
let size = end - start + 1;
// log2(1024).
const KIB_RSHIFT: u32 = 10;
// log2(1024 * 1024).
const MIB_RSHIFT: u32 = 20;
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match self.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
//! General purpose code.
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -113,6 +113,7 @@
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(int_roundings)]
#![feature(linkage)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
@ -127,6 +128,7 @@ mod panic_wait;
mod synchronization;
pub mod bsp;
pub mod common;
pub mod console;
pub mod cpu;
pub mod driver;

@ -20,6 +20,7 @@ mod arch_mmu;
mod translation_table;
use crate::common;
use core::{fmt, ops::RangeInclusive};
//--------------------------------------------------------------------------------------------------
@ -178,19 +179,7 @@ impl fmt::Display for TranslationDescriptor {
let end = *(self.virtual_range)().end();
let size = end - start + 1;
// log2(1024).
const KIB_RSHIFT: u32 = 10;
// log2(1024 * 1024).
const MIB_RSHIFT: u32 = 20;
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match self.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",

@ -682,7 +682,7 @@ Minipush 1.0
[ 0.822700] Booting on: Raspberry Pi 3
[ 0.823155] MMU online. Special regions:
[ 0.823632] 0x00080000 - 0x0008ffff | 64 KiB | C RO PX | Kernel code and RO data
[ 0.824650] 0x3f000000 - 0x4000ffff | 16 MiB | Dev RW PXN | Device MMIO
[ 0.824650] 0x3f000000 - 0x4000ffff | 17 MiB | Dev RW PXN | Device MMIO
[ 0.825539] Current privilege level: EL1
[ 0.826015] Exception handling state:
[ 0.826459] Debug: Masked
@ -726,7 +726,7 @@ Minipush 1.0
[ 0.886886] Booting on: Raspberry Pi 4
[ 0.887341] MMU online. Special regions:
[ 0.887818] 0x00080000 - 0x0008ffff | 64 KiB | C RO PX | Kernel code and RO data
[ 0.888836] 0xfe000000 - 0xff84ffff | 24 MiB | Dev RW PXN | Device MMIO
[ 0.888836] 0xfe000000 - 0xff84ffff | 25 MiB | Dev RW PXN | Device MMIO
[ 0.889725] Current privilege level: EL1
[ 0.890201] Exception handling state:
[ 0.890645] Debug: Masked
@ -2407,7 +2407,7 @@ diff -uNr 12_integrated_testing/kernel/src/exception/asynchronous.rs 13_exceptio
diff -uNr 12_integrated_testing/kernel/src/lib.rs 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs
--- 12_integrated_testing/kernel/src/lib.rs
+++ 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs
@@ -133,6 +133,7 @@
@@ -135,6 +135,7 @@
pub mod exception;
pub mod memory;
pub mod print;

@ -0,0 +1,22 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
//
// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
//! General purpose code.
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -113,6 +113,7 @@
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(int_roundings)]
#![feature(linkage)]
#![feature(panic_info_message)]
#![feature(trait_alias)]
@ -127,6 +128,7 @@ mod panic_wait;
mod synchronization;
pub mod bsp;
pub mod common;
pub mod console;
pub mod cpu;
pub mod driver;

@ -20,6 +20,7 @@ mod arch_mmu;
mod translation_table;
use crate::common;
use core::{fmt, ops::RangeInclusive};
//--------------------------------------------------------------------------------------------------
@ -178,19 +179,7 @@ impl fmt::Display for TranslationDescriptor {
let end = *(self.virtual_range)().end();
let size = end - start + 1;
// log2(1024).
const KIB_RSHIFT: u32 = 10;
// log2(1024 * 1024).
const MIB_RSHIFT: u32 = 20;
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match self.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",

@ -2053,13 +2053,10 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/bsp/raspberrypi.rs 14_v
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/common.rs 14_virtual_mem_part2_mmio_remap/kernel/src/common.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/common.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/src/common.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
+
+//! General purpose code.
+
@@ -4,6 +4,30 @@
//! General purpose code.
+/// Check if a value is aligned to a given size.
+#[inline(always)]
+pub const fn is_aligned(value: usize, alignment: usize) -> bool {
@ -2083,6 +2080,10 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/common.rs 14_virtual_me
+
+ (value + alignment - 1) & !(alignment - 1)
+}
+
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/console/null_console.rs 14_virtual_mem_part2_mmio_remap/kernel/src/console/null_console.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/console/null_console.rs
@ -2110,7 +2111,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/console/null_console.rs
+pub static NULL_CONSOLE: NullConsole = NullConsole {};
+
+//--------------------------------------------------------------------------------------------------
+// Private Code
+// Public Code
+//--------------------------------------------------------------------------------------------------
+
+impl interface::Write for NullConsole {
@ -2323,11 +2324,12 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/exception/asynchronous.
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs 14_virtual_mem_part2_mmio_remap/kernel/src/lib.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/src/lib.rs
@@ -113,8 +113,11 @@
@@ -113,9 +113,12 @@
#![feature(asm_const)]
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
+#![feature(generic_const_exprs)]
#![feature(int_roundings)]
+#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -2335,15 +2337,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs 14_virtual_mem_p
#![feature(trait_alias)]
#![no_std]
// Testing
@@ -127,6 +130,7 @@
mod synchronization;
pub mod bsp;
+pub mod common;
pub mod console;
pub mod cpu;
pub mod driver;
@@ -181,7 +185,20 @@
@@ -183,6 +186,17 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -2356,19 +2350,16 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/lib.rs 14_virtual_mem_p
+ if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
+ panic!("Enabling MMU failed: {}", e);
+ }
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
test_main();
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs 14_virtual_mem_part2_mmio_remap/kernel/src/main.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/src/main.rs
@@ -27,21 +27,31 @@
@@ -27,21 +27,29 @@
#[no_mangle]
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
@ -2386,10 +2377,9 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs 14_virtual_mem_
+ if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
+ panic!("Enabling MMU failed: {}", e);
}
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
+ memory::mmu::post_enable_init();
+
+ // Instantiate and init all device drivers.
+ if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {
+ panic!("Error instantiating drivers: {}", x);
@ -2401,11 +2391,10 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs 14_virtual_mem_
}
- bsp::driver::driver_manager().post_device_driver_init();
- // println! is usable from here on.
+ // Printing available again from here on.
// Let device drivers register and enable their handlers with the interrupt controller.
for i in bsp::driver::driver_manager().all_device_drivers() {
@@ -63,13 +73,12 @@
@@ -63,13 +71,12 @@
/// The main function running after the early init.
fn kernel_main() -> ! {
use driver::interface::DriverManager;
@ -2421,7 +2410,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs 14_virtual_mem_
let (_, privilege_level) = exception::current_privilege_level();
info!("Current privilege level: {}", privilege_level);
@@ -92,7 +101,7 @@
@@ -92,7 +99,7 @@
}
info!("Registered IRQ handlers:");
@ -2434,7 +2423,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/main.rs 14_virtual_mem_
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_record.rs 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu/mapping_record.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_record.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu/mapping_record.rs
@@ -0,0 +1,249 @@
@@ -0,0 +1,239 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
@ -2445,7 +2434,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_reco
+ AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
+ Physical, Virtual,
+};
+use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
+use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
+
+//--------------------------------------------------------------------------------------------------
+// Private Definitions
@ -2578,9 +2567,6 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_reco
+ }
+
+ pub fn print(&self) {
+ const KIB_RSHIFT: u32 = 10; // log2(1024).
+ const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
+
+ info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
+ info!(
+ " {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -2595,13 +2581,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_reco
+ let phys_start = i.phys_start_addr;
+ let phys_end_inclusive = phys_start + (size - 1);
+
+ let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
+ (size >> MIB_RSHIFT, "MiB")
+ } else if (size >> KIB_RSHIFT) > 0 {
+ (size >> KIB_RSHIFT, "KiB")
+ } else {
+ (size, "Byte")
+ };
+ let (size, unit) = common::size_human_readable_ceil(size);
+
+ let attr = match i.attribute_fields.mem_attributes {
+ MemAttributes::CacheableDRAM => "C",
@ -2620,8 +2600,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/mapping_reco
+ };
+
+ info!(
+ " {}..{} --> {}..{} | \
+ {: >3} {} | {: <3} {} {: <2} | {}",
+ " {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
+ virt_start,
+ virt_end_inclusive,
+ phys_start,
@ -2735,7 +2714,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/page_alloc.r
+ }
+
+ /// Initialize the allocator.
+ pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
+ pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
+ if self.pool.is_some() {
+ warn!("Already initialized");
+ return;
@ -3238,7 +3217,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu/types.rs 14_
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs
@@ -3,29 +3,24 @@
@@ -3,30 +3,24 @@
// Copyright (c) 2020-2022 Andre Richter <andre.o.richter@gmail.com>
//! Memory Management Unit.
@ -3262,6 +3241,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
mod translation_table;
+mod types;
-use crate::common;
-use core::{fmt, ops::RangeInclusive};
+use crate::{
+ bsp,
@ -3278,7 +3258,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
//--------------------------------------------------------------------------------------------------
// Public Definitions
@@ -45,13 +40,15 @@
@@ -46,13 +40,15 @@
/// MMU functions.
pub trait MMU {
@ -3297,7 +3277,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
/// Returns true if the MMU is enabled, false otherwise.
fn is_enabled(&self) -> bool;
@@ -64,55 +61,51 @@
@@ -65,55 +61,51 @@
/// Describes properties of an address space.
pub struct AddressSpace<const AS_SIZE: usize>;
@ -3360,7 +3340,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
+fn kernel_init_mmio_va_allocator() {
+ let region = bsp::memory::mmu::virt_mmio_remap_region();
+
+ page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
+ page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
+}
+
+/// Map a region in the kernel's translation tables.
@ -3394,7 +3374,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
}
//--------------------------------------------------------------------------------------------------
@@ -132,6 +125,9 @@
@@ -133,6 +125,9 @@
/// The granule's size.
pub const SIZE: usize = Self::size_checked();
@ -3404,7 +3384,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
/// The granule's shift, aka log2(size).
pub const SHIFT: usize = Self::SIZE.trailing_zeros() as usize;
@@ -159,110 +155,147 @@
@@ -160,98 +155,147 @@
}
}
@ -3443,31 +3423,42 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
- let end = *(self.virtual_range)().end();
- let size = end - start + 1;
-
- // log2(1024).
- const KIB_RSHIFT: u32 = 10;
-
- // log2(1024 * 1024).
- const MIB_RSHIFT: u32 = 20;
- let (size, unit) = common::size_human_readable_ceil(size);
-
- let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
- (size >> MIB_RSHIFT, "MiB")
- } else if (size >> KIB_RSHIFT) > 0 {
- (size >> KIB_RSHIFT, "KiB")
- } else {
- (size, "Byte")
- };
+ kernel_map_at_unchecked(name, virt_region, phys_region, attr)?;
- let attr = match self.attribute_fields.mem_attributes {
- MemAttributes::CacheableDRAM => "C",
- MemAttributes::Device => "Dev",
- };
+ Ok(())
+}
-
- let acc_p = match self.attribute_fields.acc_perms {
- AccessPermissions::ReadOnly => "RO",
- AccessPermissions::ReadWrite => "RW",
- };
+ kernel_map_at_unchecked(name, virt_region, phys_region, attr)?;
- let xn = if self.attribute_fields.execute_never {
- "PXN"
- } else {
- "PX"
- };
-
- write!(
- f,
- " {:#010x} - {:#010x} | {: >3} {} | {: <3} {} {: <3} | {}",
- start, end, size, unit, attr, acc_p, xn, self.name
- )
- }
+ Ok(())
}
-impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
- /// Create a new instance.
- pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self {
- Self {
- max_virt_addr_inclusive: max,
- inner: layout,
- }
- }
+/// MMIO remapping in the kernel translation tables.
+///
+/// Typically used by device drivers.
@ -3492,22 +3483,29 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
+ let num_pages = match NonZeroUsize::new(phys_region.num_pages()) {
+ None => return Err("Requested 0 pages"),
+ Some(x) => x,
};
+ };
- let xn = if self.attribute_fields.execute_never {
- "PXN"
- } else {
- "PX"
- };
- /// For a virtual address, find and return the physical output address and corresponding
- /// attributes.
- ///
- /// If the address is not found in `inner`, return an identity mapped default with normal
- /// cacheable DRAM attributes.
- pub fn virt_addr_properties(
- &self,
- virt_addr: usize,
- ) -> Result<(usize, AttributeFields), &'static str> {
- if virt_addr > self.max_virt_addr_inclusive {
- return Err("Address out of range");
- }
+ let virt_region =
+ page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.alloc(num_pages))?;
- write!(
- f,
- " {:#010x} - {:#010x} | {: >3} {} | {: <3} {} {: <3} | {}",
- start, end, size, unit, attr, acc_p, xn, self.name
- )
- }
- for i in self.inner.iter() {
- if (i.virtual_range)().contains(&virt_addr) {
- let output_addr = match i.physical_range_translation {
- Translation::Identity => virt_addr,
- Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
- };
+ kernel_map_at_unchecked(
+ name,
+ &virt_region,
@ -3561,37 +3559,8 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/src/memory/mmu.rs 14_virtua
+/// Human-readable print of all recorded kernel mappings.
+pub fn kernel_print_mappings() {
+ mapping_record::kernel_print()
}
+}
-impl<const NUM_SPECIAL_RANGES: usize> KernelVirtualLayout<{ NUM_SPECIAL_RANGES }> {
- /// Create a new instance.
- pub const fn new(max: usize, layout: [TranslationDescriptor; NUM_SPECIAL_RANGES]) -> Self {
- Self {
- max_virt_addr_inclusive: max,
- inner: layout,
- }
- }
-
- /// For a virtual address, find and return the physical output address and corresponding
- /// attributes.
- ///
- /// If the address is not found in `inner`, return an identity mapped default with normal
- /// cacheable DRAM attributes.
- pub fn virt_addr_properties(
- &self,
- virt_addr: usize,
- ) -> Result<(usize, AttributeFields), &'static str> {
- if virt_addr > self.max_virt_addr_inclusive {
- return Err("Address out of range");
- }
-
- for i in self.inner.iter() {
- if (i.virtual_range)().contains(&virt_addr) {
- let output_addr = match i.physical_range_translation {
- Translation::Identity => virt_addr,
- Translation::Offset(a) => a + (virt_addr - (i.virtual_range)().start()),
- };
-
- return Ok((output_addr, i.attribute_fields));
- }
- }
@ -3825,7 +3794,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/00_console_sanity.rs
#[no_mangle]
unsafe fn kernel_init() -> ! {
@@ -19,7 +19,20 @@
@@ -19,6 +19,17 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -3838,14 +3807,11 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/00_console_sanity.rs
+ if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
+ panic!("Enabling MMU failed: {}", e);
+ }
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
// Handshake
assert_eq!(console().read_char(), 'A');
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/01_timer_sanity.rs 14_virtual_mem_part2_mmio_remap/kernel/tests/01_timer_sanity.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/tests/01_timer_sanity.rs
@ -3859,7 +3825,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/01_timer_sanity.rs 14
use test_macros::kernel_test;
#[no_mangle]
@@ -19,7 +19,20 @@
@@ -19,6 +19,17 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -3872,19 +3838,16 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/01_timer_sanity.rs 14
+ if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
+ panic!("Enabling MMU failed: {}", e);
+ }
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/02_exception_sync_page_fault.rs 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fault.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/tests/02_exception_sync_page_fault.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fault.rs
@@ -22,18 +22,29 @@
@@ -22,19 +22,28 @@
#[no_mangle]
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
@ -3910,19 +3873,18 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/02_exception_sync_pag
+ info!("Enabling MMU failed: {}", e);
cpu::qemu_exit_failure()
}
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
+
info!("Writing beyond mapped area to address 9 GiB...");
let big_addr: u64 = 9 * 1024 * 1024 * 1024;
core::ptr::read_volatile(big_addr as *mut u64);
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/03_exception_restore_sanity.rs 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sanity.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/tests/03_exception_restore_sanity.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sanity.rs
@@ -31,18 +31,29 @@
@@ -31,19 +31,28 @@
#[no_mangle]
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
@ -3948,19 +3910,18 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/03_exception_restore_
+ info!("Enabling MMU failed: {}", e);
cpu::qemu_exit_failure()
}
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
+
info!("Making a dummy system call");
// Calling this inside a function indirectly tests if the link register is restored properly.
diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs 14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs
--- 13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sanity.rs
+++ 14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs
@@ -10,15 +10,29 @@
@@ -10,15 +10,27 @@
#![reexport_test_harness_main = "test_main"]
#![test_runner(libkernel::test_runner)]
@ -3983,11 +3944,9 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/kernel/tests/04_exception_irq_sani
+ if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
+ panic!("Enabling MMU failed: {}", e);
+ }
+ // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
+
+ memory::mmu::post_enable_init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+ // Printing available again from here on.
+
exception::asynchronous::local_irq_unmask();

@ -27,3 +27,20 @@ pub const fn align_up(value: usize, alignment: usize) -> usize {
(value + alignment - 1) & !(alignment - 1)
}
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -20,7 +20,7 @@ pub struct NullConsole;
pub static NULL_CONSOLE: NullConsole = NullConsole {};
//--------------------------------------------------------------------------------------------------
// Private Code
// Public Code
//--------------------------------------------------------------------------------------------------
impl interface::Write for NullConsole {

@ -114,6 +114,7 @@
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(generic_const_exprs)]
#![feature(int_roundings)]
#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -194,11 +195,9 @@ unsafe fn kernel_init() -> ! {
if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
panic!("Enabling MMU failed: {}", e);
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
test_main();

@ -38,7 +38,6 @@ unsafe fn kernel_init() -> ! {
if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
panic!("Enabling MMU failed: {}", e);
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
@ -51,7 +50,6 @@ unsafe fn kernel_init() -> ! {
panic!("Error loading driver: {}: {}", i.compatible(), x);
}
}
// Printing available again from here on.
// Let device drivers register and enable their handlers with the interrupt controller.
for i in bsp::driver::driver_manager().all_device_drivers() {

@ -81,7 +81,7 @@ use translation_table::interface::TranslationTable;
fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
}
/// Map a region in the kernel's translation tables.

@ -8,7 +8,7 @@ use super::{
AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
Physical, Virtual,
};
use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
//--------------------------------------------------------------------------------------------------
// Private Definitions
@ -141,9 +141,6 @@ impl MappingRecord {
}
pub fn print(&self) {
const KIB_RSHIFT: u32 = 10; // log2(1024).
const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
info!(
" {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -158,13 +155,7 @@ impl MappingRecord {
let phys_start = i.phys_start_addr;
let phys_end_inclusive = phys_start + (size - 1);
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match i.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",
@ -183,8 +174,7 @@ impl MappingRecord {
};
info!(
" {}..{} --> {}..{} | \
{: >3} {} | {: <3} {} {: <2} | {}",
" {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
virt_start,
virt_end_inclusive,
phys_start,

@ -44,7 +44,7 @@ impl<ATYPE: AddressType> PageAllocator<ATYPE> {
}
/// Initialize the allocator.
pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
if self.pool.is_some() {
warn!("Already initialized");
return;

@ -28,11 +28,9 @@ unsafe fn kernel_init() -> ! {
if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
panic!("Enabling MMU failed: {}", e);
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
// Handshake
assert_eq!(console().read_char(), 'A');

@ -28,11 +28,9 @@ unsafe fn kernel_init() -> ! {
if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
panic!("Enabling MMU failed: {}", e);
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.

@ -40,11 +40,9 @@ unsafe fn kernel_init() -> ! {
info!("Enabling MMU failed: {}", e);
cpu::qemu_exit_failure()
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
info!("Writing beyond mapped area to address 9 GiB...");
let big_addr: u64 = 9 * 1024 * 1024 * 1024;

@ -49,11 +49,9 @@ unsafe fn kernel_init() -> ! {
info!("Enabling MMU failed: {}", e);
cpu::qemu_exit_failure()
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
info!("Making a dummy system call");

@ -27,11 +27,9 @@ unsafe fn kernel_init() -> ! {
if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
panic!("Enabling MMU failed: {}", e);
}
// Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
memory::mmu::post_enable_init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Printing available again from here on.
exception::asynchronous::local_irq_unmask();

@ -1315,7 +1315,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/bsp/raspberrypi/memory/mmu.
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/lib.rs 15_virtual_mem_part3_precomputed_tables/kernel/src/lib.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/src/lib.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/src/lib.rs
@@ -185,20 +185,8 @@
@@ -186,17 +186,7 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -1328,19 +1328,17 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/lib.rs 15_virtual_mem_part3
- if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
- panic!("Enabling MMU failed: {}", e);
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
memory::mmu::post_enable_init();
- memory::mmu::post_enable_init();
+ memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
test_main();
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/main.rs 15_virtual_mem_part3_precomputed_tables/kernel/src/main.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/src/main.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/src/main.rs
@@ -17,29 +17,17 @@
@@ -17,29 +17,18 @@
/// Early init code.
///
@ -1368,20 +1366,13 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/main.rs 15_virtual_mem_part
- if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
- panic!("Enabling MMU failed: {}", e);
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
memory::mmu::post_enable_init();
- memory::mmu::post_enable_init();
+ memory::init();
// Instantiate and init all device drivers.
@@ -51,7 +39,6 @@
panic!("Error loading driver: {}: {}", i.compatible(), x);
}
}
- // Printing available again from here on.
// Let device drivers register and enable their handlers with the interrupt controller.
for i in bsp::driver::driver_manager().all_device_drivers() {
@@ -60,6 +47,8 @@
if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {
@@ -58,6 +47,8 @@
}
}
@ -1494,7 +1485,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
};
use core::{fmt, num::NonZeroUsize};
@@ -73,7 +74,7 @@
@@ -73,17 +74,9 @@
// Private Code
//--------------------------------------------------------------------------------------------------
use interface::MMU;
@ -1502,8 +1493,18 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
+use synchronization::interface::ReadWriteEx;
use translation_table::interface::TranslationTable;
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
@@ -101,13 +102,21 @@
-/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
-/// MMIO VA allocator with it.
-fn kernel_init_mmio_va_allocator() {
- let region = bsp::memory::mmu::virt_mmio_remap_region();
-
- page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
-}
-
/// Map a region in the kernel's translation tables.
///
/// No input checks done, input is passed through to the architectural implementation.
@@ -101,13 +94,21 @@
bsp::memory::mmu::kernel_translation_tables()
.write(|tables| tables.map_at(virt_region, phys_region, attr))?;
@ -1528,7 +1529,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
//--------------------------------------------------------------------------------------------------
// Public Code
//--------------------------------------------------------------------------------------------------
@@ -155,27 +164,16 @@
@@ -155,27 +156,24 @@
}
}
@ -1541,6 +1542,14 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
-/// - See `kernel_map_at_unchecked()`.
-/// - Does not prevent aliasing. Currently, the callers must be trusted.
-pub unsafe fn kernel_map_at(
+/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
+/// MMIO VA allocator with it.
+pub fn kernel_init_mmio_va_allocator() {
+ let region = bsp::memory::mmu::virt_mmio_remap_region();
+
+ page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
+}
+
+/// Add an entry to the mapping info record.
+pub fn kernel_add_mapping_record(
name: &'static str,
@ -1561,15 +1570,15 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
}
/// MMIO remapping in the kernel translation tables.
@@ -224,21 +222,24 @@
@@ -224,21 +222,29 @@
Ok(virt_addr + offset_into_start_page)
}
-/// Map the kernel's binary. Returns the translation table's base address.
-///
-/// # Safety
+/// Try to translate a kernel virtual page address to a physical page address.
///
-/// # Safety
-///
-/// - See [`bsp::memory::mmu::kernel_map_binary()`].
-pub unsafe fn kernel_map_binary() -> Result<Address<Physical>, &'static str> {
- let phys_kernel_tables_base_addr =
@ -1577,8 +1586,6 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
- tables.init();
- tables.phys_base_address()
- });
-
- bsp::memory::mmu::kernel_map_binary()?;
+/// Will only succeed if there exists a valid mapping for the input page.
+pub fn try_kernel_virt_page_addr_to_phys_page_addr(
+ virt_page_addr: PageAddress<Virtual>,
@ -1587,7 +1594,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
+ .read(|tables| tables.try_virt_page_addr_to_phys_page_addr(virt_page_addr))
+}
- Ok(phys_kernel_tables_base_addr)
- bsp::memory::mmu::kernel_map_binary()?;
+/// Try to get the attributes of a kernel page.
+///
+/// Will only succeed if there exists a valid mapping for the input page.
@ -1596,10 +1603,16 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
+) -> Result<AttributeFields, &'static str> {
+ bsp::memory::mmu::kernel_translation_tables()
+ .read(|tables| tables.try_page_attributes(virt_page_addr))
+}
- Ok(phys_kernel_tables_base_addr)
+/// Human-readable print of all recorded kernel mappings.
+pub fn kernel_print_mappings() {
+ mapping_record::kernel_print()
}
/// Enable the MMU and data + instruction caching.
@@ -246,6 +247,7 @@
@@ -246,56 +252,9 @@
/// # Safety
///
/// - Crucial function during kernel init. Changes the the complete memory view of the processor.
@ -1607,11 +1620,19 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
pub unsafe fn enable_mmu_and_caching(
phys_tables_base_addr: Address<Physical>,
) -> Result<(), MMUEnableError> {
@@ -261,41 +263,3 @@
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr)
}
-
-/// Finish initialization of the MMU subsystem.
-pub fn post_enable_init() {
- kernel_init_mmio_va_allocator();
-}
-
-/// Human-readable print of all recorded kernel mappings.
-pub fn kernel_print_mappings() {
- mapping_record::kernel_print()
-}
-
-//--------------------------------------------------------------------------------------------------
-// Testing
-//--------------------------------------------------------------------------------------------------
@ -1650,10 +1671,26 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory/mmu.rs 15_virtual_me
- }
-}
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/src/memory.rs 15_virtual_mem_part3_precomputed_tables/kernel/src/memory.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/src/memory.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/src/memory.rs
@@ -136,6 +136,11 @@
}
}
+/// Initialize the memory subsystem.
+pub fn init() {
+ mmu::kernel_init_mmio_va_allocator();
+}
+
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/00_console_sanity.rs 15_virtual_mem_part3_precomputed_tables/kernel/tests/00_console_sanity.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/tests/00_console_sanity.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/tests/00_console_sanity.rs
@@ -19,20 +19,8 @@
@@ -19,17 +19,7 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -1666,19 +1703,17 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/00_console_sanity.rs 15_v
- if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
- panic!("Enabling MMU failed: {}", e);
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
memory::mmu::post_enable_init();
- memory::mmu::post_enable_init();
+ memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
// Handshake
assert_eq!(console().read_char(), 'A');
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/01_timer_sanity.rs 15_virtual_mem_part3_precomputed_tables/kernel/tests/01_timer_sanity.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/tests/01_timer_sanity.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/tests/01_timer_sanity.rs
@@ -19,20 +19,8 @@
@@ -19,17 +19,7 @@
use driver::interface::DriverManager;
exception::handling_init();
@ -1691,23 +1726,21 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/01_timer_sanity.rs 15_vir
- if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
- panic!("Enabling MMU failed: {}", e);
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
memory::mmu::post_enable_init();
- memory::mmu::post_enable_init();
+ memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fault.rs 15_virtual_mem_part3_precomputed_tables/kernel/tests/02_exception_sync_page_fault.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fault.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/tests/02_exception_sync_page_fault.rs
@@ -24,28 +24,12 @@
@@ -24,26 +24,12 @@
use driver::interface::DriverManager;
exception::handling_init();
+ memory::mmu::post_enable_init();
+ memory::init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.
@ -1725,11 +1758,9 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fa
- info!("Enabling MMU failed: {}", e);
- cpu::qemu_exit_failure()
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
- memory::mmu::post_enable_init();
- bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
-
info!("Writing beyond mapped area to address 9 GiB...");
let big_addr: u64 = 9 * 1024 * 1024 * 1024;
@ -1738,11 +1769,11 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/02_exception_sync_page_fa
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sanity.rs 15_virtual_mem_part3_precomputed_tables/kernel/tests/03_exception_restore_sanity.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sanity.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/tests/03_exception_restore_sanity.rs
@@ -33,28 +33,12 @@
@@ -33,26 +33,12 @@
use driver::interface::DriverManager;
exception::handling_init();
+ memory::mmu::post_enable_init();
+ memory::init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.
@ -1760,11 +1791,9 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sani
- info!("Enabling MMU failed: {}", e);
- cpu::qemu_exit_failure()
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
- memory::mmu::post_enable_init();
- bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
-
info!("Making a dummy system call");
@ -1773,7 +1802,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/03_exception_restore_sani
diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs 15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs
--- 14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.rs
+++ 15_virtual_mem_part3_precomputed_tables/kernel/tests/04_exception_irq_sanity.rs
@@ -17,22 +17,10 @@
@@ -17,20 +17,10 @@
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
@ -1787,11 +1816,10 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/kernel/tests/04_exception_irq_sanity.r
- if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) {
- panic!("Enabling MMU failed: {}", e);
- }
- // Printing will silently fail from here on, because the driver's MMIO is not remapped yet.
-
memory::mmu::post_enable_init();
- memory::mmu::post_enable_init();
+ memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
- // Printing available again from here on.
+ exception::handling_init();
exception::asynchronous::local_irq_unmask();

@ -27,3 +27,20 @@ pub const fn align_up(value: usize, alignment: usize) -> usize {
(value + alignment - 1) & !(alignment - 1)
}
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -20,7 +20,7 @@ pub struct NullConsole;
pub static NULL_CONSOLE: NullConsole = NullConsole {};
//--------------------------------------------------------------------------------------------------
// Private Code
// Public Code
//--------------------------------------------------------------------------------------------------
impl interface::Write for NullConsole {

@ -114,6 +114,7 @@
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(generic_const_exprs)]
#![feature(int_roundings)]
#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -185,7 +186,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
test_main();

@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
// Instantiate and init all device drivers.
if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {

@ -136,6 +136,11 @@ impl fmt::Display for Address<Virtual> {
}
}
/// Initialize the memory subsystem.
pub fn init() {
mmu::kernel_init_mmio_va_allocator();
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------

@ -77,14 +77,6 @@ use interface::MMU;
use synchronization::interface::ReadWriteEx;
use translation_table::interface::TranslationTable;
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
}
/// Map a region in the kernel's translation tables.
///
/// No input checks done, input is passed through to the architectural implementation.
@ -164,6 +156,14 @@ impl<const AS_SIZE: usize> AddressSpace<AS_SIZE> {
}
}
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
pub fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
}
/// Add an entry to the mapping info record.
pub fn kernel_add_mapping_record(
name: &'static str,
@ -242,6 +242,11 @@ pub fn try_kernel_page_attributes(
.read(|tables| tables.try_page_attributes(virt_page_addr))
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}
/// Enable the MMU and data + instruction caching.
///
/// # Safety
@ -253,13 +258,3 @@ pub unsafe fn enable_mmu_and_caching(
) -> Result<(), MMUEnableError> {
arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr)
}
/// Finish initialization of the MMU subsystem.
pub fn post_enable_init() {
kernel_init_mmio_va_allocator();
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}

@ -8,7 +8,7 @@ use super::{
AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
Physical, Virtual,
};
use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
//--------------------------------------------------------------------------------------------------
// Private Definitions
@ -141,9 +141,6 @@ impl MappingRecord {
}
pub fn print(&self) {
const KIB_RSHIFT: u32 = 10; // log2(1024).
const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
info!(
" {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -158,13 +155,7 @@ impl MappingRecord {
let phys_start = i.phys_start_addr;
let phys_end_inclusive = phys_start + (size - 1);
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match i.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",
@ -183,8 +174,7 @@ impl MappingRecord {
};
info!(
" {}..{} --> {}..{} | \
{: >3} {} | {: <3} {} {: <2} | {}",
" {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
virt_start,
virt_end_inclusive,
phys_start,

@ -44,7 +44,7 @@ impl<ATYPE: AddressType> PageAllocator<ATYPE> {
}
/// Initialize the allocator.
pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
if self.pool.is_some() {
warn!("Already initialized");
return;

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Handshake

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.

@ -24,7 +24,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -33,7 +33,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -17,7 +17,7 @@ use test_macros::kernel_test;
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
exception::handling_init();

@ -729,7 +729,7 @@ diff -uNr 15_virtual_mem_part3_precomputed_tables/kernel/src/bsp/raspberrypi/mem
diff -uNr 15_virtual_mem_part3_precomputed_tables/kernel/src/lib.rs 16_virtual_mem_part4_higher_half_kernel/kernel/src/lib.rs
--- 15_virtual_mem_part3_precomputed_tables/kernel/src/lib.rs
+++ 16_virtual_mem_part4_higher_half_kernel/kernel/src/lib.rs
@@ -153,11 +153,6 @@
@@ -154,11 +154,6 @@
)
}

@ -27,3 +27,20 @@ pub const fn align_up(value: usize, alignment: usize) -> usize {
(value + alignment - 1) & !(alignment - 1)
}
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -20,7 +20,7 @@ pub struct NullConsole;
pub static NULL_CONSOLE: NullConsole = NullConsole {};
//--------------------------------------------------------------------------------------------------
// Private Code
// Public Code
//--------------------------------------------------------------------------------------------------
impl interface::Write for NullConsole {

@ -114,6 +114,7 @@
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(generic_const_exprs)]
#![feature(int_roundings)]
#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -180,7 +181,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
test_main();

@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
// Instantiate and init all device drivers.
if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {

@ -136,6 +136,11 @@ impl fmt::Display for Address<Virtual> {
}
}
/// Initialize the memory subsystem.
pub fn init() {
mmu::kernel_init_mmio_va_allocator();
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------

@ -82,14 +82,6 @@ use interface::MMU;
use synchronization::interface::ReadWriteEx;
use translation_table::interface::TranslationTable;
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
}
/// Map a region in the kernel's translation tables.
///
/// No input checks done, input is passed through to the architectural implementation.
@ -169,6 +161,14 @@ impl<const AS_SIZE: usize> AddressSpace<AS_SIZE> {
}
}
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
pub fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
}
/// Add an entry to the mapping info record.
pub fn kernel_add_mapping_record(
name: &'static str,
@ -247,6 +247,11 @@ pub fn try_kernel_page_attributes(
.read(|tables| tables.try_page_attributes(virt_page_addr))
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}
/// Enable the MMU and data + instruction caching.
///
/// # Safety
@ -258,13 +263,3 @@ pub unsafe fn enable_mmu_and_caching(
) -> Result<(), MMUEnableError> {
arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr)
}
/// Finish initialization of the MMU subsystem.
pub fn post_enable_init() {
kernel_init_mmio_va_allocator();
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}

@ -8,7 +8,7 @@ use super::{
AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
Physical, Virtual,
};
use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
//--------------------------------------------------------------------------------------------------
// Private Definitions
@ -141,9 +141,6 @@ impl MappingRecord {
}
pub fn print(&self) {
const KIB_RSHIFT: u32 = 10; // log2(1024).
const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
info!(
" {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -158,13 +155,7 @@ impl MappingRecord {
let phys_start = i.phys_start_addr;
let phys_end_inclusive = phys_start + (size - 1);
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match i.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",
@ -183,8 +174,7 @@ impl MappingRecord {
};
info!(
" {}..{} --> {}..{} | \
{: >3} {} | {: <3} {} {: <2} | {}",
" {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
virt_start,
virt_end_inclusive,
phys_start,

@ -44,7 +44,7 @@ impl<ATYPE: AddressType> PageAllocator<ATYPE> {
}
/// Initialize the allocator.
pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
if self.pool.is_some() {
warn!("Already initialized");
return;

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Handshake

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.

@ -24,7 +24,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -33,7 +33,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -17,7 +17,7 @@ use test_macros::kernel_test;
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
exception::handling_init();

@ -332,7 +332,7 @@ diff -uNr 16_virtual_mem_part4_higher_half_kernel/kernel/src/bsp/raspberrypi/mem
diff -uNr 16_virtual_mem_part4_higher_half_kernel/kernel/src/lib.rs 17_kernel_symbols/kernel/src/lib.rs
--- 16_virtual_mem_part4_higher_half_kernel/kernel/src/lib.rs
+++ 17_kernel_symbols/kernel/src/lib.rs
@@ -138,6 +138,7 @@
@@ -139,6 +139,7 @@
pub mod memory;
pub mod print;
pub mod state;

@ -27,3 +27,20 @@ pub const fn align_up(value: usize, alignment: usize) -> usize {
(value + alignment - 1) & !(alignment - 1)
}
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -20,7 +20,7 @@ pub struct NullConsole;
pub static NULL_CONSOLE: NullConsole = NullConsole {};
//--------------------------------------------------------------------------------------------------
// Private Code
// Public Code
//--------------------------------------------------------------------------------------------------
impl interface::Write for NullConsole {

@ -114,6 +114,7 @@
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(generic_const_exprs)]
#![feature(int_roundings)]
#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -181,7 +182,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
test_main();

@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
// Instantiate and init all device drivers.
if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {

@ -136,6 +136,11 @@ impl fmt::Display for Address<Virtual> {
}
}
/// Initialize the memory subsystem.
pub fn init() {
mmu::kernel_init_mmio_va_allocator();
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------

@ -82,14 +82,6 @@ use interface::MMU;
use synchronization::interface::ReadWriteEx;
use translation_table::interface::TranslationTable;
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
}
/// Map a region in the kernel's translation tables.
///
/// No input checks done, input is passed through to the architectural implementation.
@ -169,6 +161,14 @@ impl<const AS_SIZE: usize> AddressSpace<AS_SIZE> {
}
}
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
pub fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
}
/// Add an entry to the mapping info record.
pub fn kernel_add_mapping_record(
name: &'static str,
@ -247,6 +247,11 @@ pub fn try_kernel_page_attributes(
.read(|tables| tables.try_page_attributes(virt_page_addr))
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}
/// Enable the MMU and data + instruction caching.
///
/// # Safety
@ -258,13 +263,3 @@ pub unsafe fn enable_mmu_and_caching(
) -> Result<(), MMUEnableError> {
arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr)
}
/// Finish initialization of the MMU subsystem.
pub fn post_enable_init() {
kernel_init_mmio_va_allocator();
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}

@ -8,7 +8,7 @@ use super::{
AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
Physical, Virtual,
};
use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
//--------------------------------------------------------------------------------------------------
// Private Definitions
@ -141,9 +141,6 @@ impl MappingRecord {
}
pub fn print(&self) {
const KIB_RSHIFT: u32 = 10; // log2(1024).
const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
info!(
" {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -158,13 +155,7 @@ impl MappingRecord {
let phys_start = i.phys_start_addr;
let phys_end_inclusive = phys_start + (size - 1);
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match i.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",
@ -183,8 +174,7 @@ impl MappingRecord {
};
info!(
" {}..{} --> {}..{} | \
{: >3} {} | {: <3} {} {: <2} | {}",
" {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
virt_start,
virt_end_inclusive,
phys_start,

@ -44,7 +44,7 @@ impl<ATYPE: AddressType> PageAllocator<ATYPE> {
}
/// Initialize the allocator.
pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
if self.pool.is_some() {
warn!("Already initialized");
return;

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Handshake

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.

@ -24,7 +24,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -33,7 +33,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -17,7 +17,7 @@ use test_macros::kernel_test;
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
exception::handling_init();

@ -727,7 +727,7 @@ diff -uNr 17_kernel_symbols/kernel/src/_arch/aarch64/exception.s 18_backtrace/ke
diff -uNr 17_kernel_symbols/kernel/src/backtrace.rs 18_backtrace/kernel/src/backtrace.rs
--- 17_kernel_symbols/kernel/src/backtrace.rs
+++ 18_backtrace/kernel/src/backtrace.rs
@@ -0,0 +1,112 @@
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: MIT OR Apache-2.0
+//
+// Copyright (c) 2022 Andre Richter <andre.o.richter@gmail.com>
@ -790,7 +790,9 @@ diff -uNr 17_kernel_symbols/kernel/src/backtrace.rs 18_backtrace/kernel/src/back
+ |maybe_iter: Option<&mut dyn Iterator<Item = BacktraceItem>>| match maybe_iter {
+ None => fmt_res = writeln!(f, "ERROR! No valid stack frame found"),
+ Some(iter) => {
+ for (i, backtrace_res) in iter.enumerate() {
+ // Since the backtrace is printed, the first function is always
+ // core::fmt::write. Skip 1 so it is excluded and doesn't bloat the output.
+ for (i, backtrace_res) in iter.skip(1).enumerate() {
+ match backtrace_res {
+ BacktraceItem::InvalidFramePointer(addr) => {
+ fmt_res = writeln!(
@ -909,7 +911,7 @@ diff -uNr 17_kernel_symbols/kernel/src/bsp/raspberrypi/memory/mmu.rs 18_backtrac
diff -uNr 17_kernel_symbols/kernel/src/lib.rs 18_backtrace/kernel/src/lib.rs
--- 17_kernel_symbols/kernel/src/lib.rs
+++ 18_backtrace/kernel/src/lib.rs
@@ -129,6 +129,7 @@
@@ -130,6 +130,7 @@
mod panic_wait;
mod synchronization;
@ -1062,7 +1064,7 @@ diff -uNr 17_kernel_symbols/kernel/tests/05_backtrace_sanity.rs 18_backtrace/ker
+ use driver::interface::DriverManager;
+
+ exception::handling_init();
+ memory::mmu::post_enable_init();
+ memory::init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+
+ nested();
@ -1133,7 +1135,7 @@ diff -uNr 17_kernel_symbols/kernel/tests/06_backtrace_invalid_frame.rs 18_backtr
+ use driver::interface::DriverManager;
+
+ exception::handling_init();
+ memory::mmu::post_enable_init();
+ memory::init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+
+ nested();
@ -1208,7 +1210,7 @@ diff -uNr 17_kernel_symbols/kernel/tests/07_backtrace_invalid_link.rs 18_backtra
+ use driver::interface::DriverManager;
+
+ exception::handling_init();
+ memory::mmu::post_enable_init();
+ memory::init();
+ bsp::driver::driver_manager().qemu_bring_up_console();
+
+ nested_1();
@ -1264,4 +1266,50 @@ diff -uNr 17_kernel_symbols/Makefile 18_backtrace/Makefile
$(call color_header, "Launching GDB")
@$(DOCKER_GDB) gdb-multiarch -q $(KERNEL_ELF)
diff -uNr 17_kernel_symbols/tools/translation_table_tool/bsp.rb 18_backtrace/tools/translation_table_tool/bsp.rb
--- 17_kernel_symbols/tools/translation_table_tool/bsp.rb
+++ 18_backtrace/tools/translation_table_tool/bsp.rb
@@ -45,6 +45,10 @@
raise
end
- x.scan(/\d+/).join.to_i(16)
+ # Extract the hex literal with underscores like 0x0123_abcd.
+ x = x.scan(/0x[\h_]*/)[0]
+
+ # Further remove x and _ and convert to int.
+ x.scan(/\h+/).join.to_i(16)
end
end
diff -uNr 17_kernel_symbols/tools/translation_table_tool/generic.rb 18_backtrace/tools/translation_table_tool/generic.rb
--- 17_kernel_symbols/tools/translation_table_tool/generic.rb
+++ 18_backtrace/tools/translation_table_tool/generic.rb
@@ -109,13 +109,23 @@
@attributes = attributes
end
+ def size_human_readable(size)
+ if size >= (1024 * 1024)
+ "#{(size / (1024 * 1024)).to_s.rjust(3)} MiB"
+ elsif size >= 1024
+ "#{(size / 1024).to_s.rjust(3)} KiB"
+ else
+ raise
+ end
+ end
+
def to_s
name = @name.ljust(self.class.max_section_name_length)
virt_start = @virt_region.first.to_hex_underscore(with_leading_zeros: true)
phys_start = @phys_region.first.to_hex_underscore(with_leading_zeros: true)
- size = ((@virt_region.size * 65_536) / 1024).to_s.rjust(3)
+ size = size_human_readable(@virt_region.size * 65_536)
- "#{name} | #{virt_start} | #{phys_start} | #{size} KiB | #{@attributes}"
+ "#{name} | #{virt_start} | #{phys_start} | #{size} | #{@attributes}"
end
def self.print_divider
```

@ -60,7 +60,9 @@ impl fmt::Display for Backtrace {
|maybe_iter: Option<&mut dyn Iterator<Item = BacktraceItem>>| match maybe_iter {
None => fmt_res = writeln!(f, "ERROR! No valid stack frame found"),
Some(iter) => {
for (i, backtrace_res) in iter.enumerate() {
// Since the backtrace is printed, the first function is always
// core::fmt::write. Skip 1 so it is excluded and doesn't bloat the output.
for (i, backtrace_res) in iter.skip(1).enumerate() {
match backtrace_res {
BacktraceItem::InvalidFramePointer(addr) => {
fmt_res = writeln!(

@ -27,3 +27,20 @@ pub const fn align_up(value: usize, alignment: usize) -> usize {
(value + alignment - 1) & !(alignment - 1)
}
/// Convert a size into human readable format.
pub const fn size_human_readable_ceil(size: usize) -> (usize, &'static str) {
const KIB: usize = 1024;
const MIB: usize = 1024 * 1024;
const GIB: usize = 1024 * 1024 * 1024;
if (size / GIB) > 0 {
(size.div_ceil(GIB), "GiB")
} else if (size / MIB) > 0 {
(size.div_ceil(MIB), "MiB")
} else if (size / KIB) > 0 {
(size.div_ceil(KIB), "KiB")
} else {
(size, "Byte")
}
}

@ -20,7 +20,7 @@ pub struct NullConsole;
pub static NULL_CONSOLE: NullConsole = NullConsole {};
//--------------------------------------------------------------------------------------------------
// Private Code
// Public Code
//--------------------------------------------------------------------------------------------------
impl interface::Write for NullConsole {

@ -114,6 +114,7 @@
#![feature(core_intrinsics)]
#![feature(format_args_nl)]
#![feature(generic_const_exprs)]
#![feature(int_roundings)]
#![feature(is_sorted)]
#![feature(linkage)]
#![feature(panic_info_message)]
@ -182,7 +183,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
test_main();

@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
// Instantiate and init all device drivers.
if let Err(x) = bsp::driver::driver_manager().instantiate_drivers() {

@ -160,6 +160,11 @@ impl fmt::Display for Address<Virtual> {
}
}
/// Initialize the memory subsystem.
pub fn init() {
mmu::kernel_init_mmio_va_allocator();
}
//--------------------------------------------------------------------------------------------------
// Testing
//--------------------------------------------------------------------------------------------------

@ -82,14 +82,6 @@ use interface::MMU;
use synchronization::interface::ReadWriteEx;
use translation_table::interface::TranslationTable;
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.initialize(region));
}
/// Map a region in the kernel's translation tables.
///
/// No input checks done, input is passed through to the architectural implementation.
@ -169,6 +161,14 @@ impl<const AS_SIZE: usize> AddressSpace<AS_SIZE> {
}
}
/// Query the BSP for the reserved virtual addresses for MMIO remapping and initialize the kernel's
/// MMIO VA allocator with it.
pub fn kernel_init_mmio_va_allocator() {
let region = bsp::memory::mmu::virt_mmio_remap_region();
page_alloc::kernel_mmio_va_allocator().lock(|allocator| allocator.init(region));
}
/// Add an entry to the mapping info record.
pub fn kernel_add_mapping_record(
name: &'static str,
@ -247,6 +247,11 @@ pub fn try_kernel_page_attributes(
.read(|tables| tables.try_page_attributes(virt_page_addr))
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}
/// Enable the MMU and data + instruction caching.
///
/// # Safety
@ -258,13 +263,3 @@ pub unsafe fn enable_mmu_and_caching(
) -> Result<(), MMUEnableError> {
arch_mmu::mmu().enable_mmu_and_caching(phys_tables_base_addr)
}
/// Finish initialization of the MMU subsystem.
pub fn post_enable_init() {
kernel_init_mmio_va_allocator();
}
/// Human-readable print of all recorded kernel mappings.
pub fn kernel_print_mappings() {
mapping_record::kernel_print()
}

@ -8,7 +8,7 @@ use super::{
AccessPermissions, Address, AttributeFields, MMIODescriptor, MemAttributes, MemoryRegion,
Physical, Virtual,
};
use crate::{bsp, info, synchronization, synchronization::InitStateLock, warn};
use crate::{bsp, common, info, synchronization, synchronization::InitStateLock, warn};
//--------------------------------------------------------------------------------------------------
// Private Definitions
@ -141,9 +141,6 @@ impl MappingRecord {
}
pub fn print(&self) {
const KIB_RSHIFT: u32 = 10; // log2(1024).
const MIB_RSHIFT: u32 = 20; // log2(1024 * 1024).
info!(" -------------------------------------------------------------------------------------------------------------------------------------------");
info!(
" {:^44} {:^30} {:^7} {:^9} {:^35}",
@ -158,13 +155,7 @@ impl MappingRecord {
let phys_start = i.phys_start_addr;
let phys_end_inclusive = phys_start + (size - 1);
let (size, unit) = if (size >> MIB_RSHIFT) > 0 {
(size >> MIB_RSHIFT, "MiB")
} else if (size >> KIB_RSHIFT) > 0 {
(size >> KIB_RSHIFT, "KiB")
} else {
(size, "Byte")
};
let (size, unit) = common::size_human_readable_ceil(size);
let attr = match i.attribute_fields.mem_attributes {
MemAttributes::CacheableDRAM => "C",
@ -183,8 +174,7 @@ impl MappingRecord {
};
info!(
" {}..{} --> {}..{} | \
{: >3} {} | {: <3} {} {: <2} | {}",
" {}..{} --> {}..{} | {:>3} {} | {:<3} {} {:<2} | {}",
virt_start,
virt_end_inclusive,
phys_start,

@ -44,7 +44,7 @@ impl<ATYPE: AddressType> PageAllocator<ATYPE> {
}
/// Initialize the allocator.
pub fn initialize(&mut self, pool: MemoryRegion<ATYPE>) {
pub fn init(&mut self, pool: MemoryRegion<ATYPE>) {
if self.pool.is_some() {
warn!("Already initialized");
return;

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Handshake

@ -19,7 +19,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// Depending on CPU arch, some timer bring-up code could go here. Not needed for the RPi.

@ -24,7 +24,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -33,7 +33,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
// This line will be printed as the test header.

@ -17,7 +17,7 @@ use test_macros::kernel_test;
unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
exception::handling_init();

@ -23,7 +23,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
nested();

@ -25,7 +25,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
nested();

@ -30,7 +30,7 @@ unsafe fn kernel_init() -> ! {
use driver::interface::DriverManager;
exception::handling_init();
memory::mmu::post_enable_init();
memory::init();
bsp::driver::driver_manager().qemu_bring_up_console();
nested_1();

@ -45,6 +45,10 @@ class RaspberryPi
raise
end
x.scan(/\d+/).join.to_i(16)
# Extract the hex literal with underscores like 0x0123_abcd.
x = x.scan(/0x[\h_]*/)[0]
# Further remove x and _ and convert to int.
x.scan(/\h+/).join.to_i(16)
end
end

@ -109,13 +109,23 @@ class MappingDescriptor
@attributes = attributes
end
def size_human_readable(size)
if size >= (1024 * 1024)
"#{(size / (1024 * 1024)).to_s.rjust(3)} MiB"
elsif size >= 1024
"#{(size / 1024).to_s.rjust(3)} KiB"
else
raise
end
end
def to_s
name = @name.ljust(self.class.max_section_name_length)
virt_start = @virt_region.first.to_hex_underscore(with_leading_zeros: true)
phys_start = @phys_region.first.to_hex_underscore(with_leading_zeros: true)
size = ((@virt_region.size * 65_536) / 1024).to_s.rjust(3)
size = size_human_readable(@virt_region.size * 65_536)
"#{name} | #{virt_start} | #{phys_start} | #{size} KiB | #{@attributes}"
"#{name} | #{virt_start} | #{phys_start} | #{size} | #{@attributes}"
end
def self.print_divider

Loading…
Cancel
Save