From 722e8b72329f5462945190df7843be8a3c36edfa Mon Sep 17 00:00:00 2001 From: Andre Richter Date: Thu, 31 Mar 2022 22:09:17 +0200 Subject: [PATCH 1/2] Print a timestamp on panic --- 07_timestamps/README.md | 72 +++++++++++------- 07_timestamps/src/_arch/aarch64/time.rs | 2 + 07_timestamps/src/panic_wait.rs | 17 ++++- 07_timestamps/src/print.rs | 36 +++------ 08_hw_debug_JTAG/src/_arch/aarch64/time.rs | 2 + 08_hw_debug_JTAG/src/panic_wait.rs | 17 ++++- 08_hw_debug_JTAG/src/print.rs | 36 +++------ 09_privilege_level/src/_arch/aarch64/time.rs | 2 + 09_privilege_level/src/panic_wait.rs | 17 ++++- 09_privilege_level/src/print.rs | 36 +++------ .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- .../src/print.rs | 36 +++------ .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- 11_exceptions_part1_groundwork/src/print.rs | 36 +++------ 12_integrated_testing/README.md | 15 ++-- .../src/_arch/aarch64/time.rs | 2 + 12_integrated_testing/src/panic_wait.rs | 17 ++++- 12_integrated_testing/src/print.rs | 36 +++------ .../tests/02_exception_sync_page_fault.rs | 6 +- 13_exceptions_part2_peripheral_IRQs/README.md | 10 +-- .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- .../src/print.rs | 36 +++------ .../tests/02_exception_sync_page_fault.rs | 6 +- 14_virtual_mem_part2_mmio_remap/README.md | 8 +- .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- 14_virtual_mem_part2_mmio_remap/src/print.rs | 36 +++------ .../tests/02_exception_sync_page_fault.rs | 8 +- .../README.md | 6 +- .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- .../src/print.rs | 36 +++------ .../tests/02_exception_sync_page_fault.rs | 4 +- .../README.md | 4 +- .../src/_arch/aarch64/time.rs | 2 + .../src/panic_wait.rs | 17 ++++- .../src/print.rs | 36 +++------ .../tests/02_exception_sync_page_fault.rs | 4 +- X1_JTAG_boot/jtag_boot_rpi3.img | Bin 7808 -> 7808 bytes X1_JTAG_boot/jtag_boot_rpi4.img | Bin 6528 -> 6832 bytes X1_JTAG_boot/src/_arch/aarch64/time.rs | 2 + X1_JTAG_boot/src/panic_wait.rs | 17 ++++- X1_JTAG_boot/src/print.rs | 36 +++------ 46 files changed, 400 insertions(+), 348 deletions(-) diff --git a/07_timestamps/README.md b/07_timestamps/README.md index 3e110030..762e3cb3 100644 --- a/07_timestamps/README.md +++ b/07_timestamps/README.md @@ -248,7 +248,7 @@ diff -uNr 06_uart_chainloader/src/_arch/aarch64/cpu.rs 07_timestamps/src/_arch/a diff -uNr 06_uart_chainloader/src/_arch/aarch64/time.rs 07_timestamps/src/_arch/aarch64/time.rs --- 06_uart_chainloader/src/_arch/aarch64/time.rs +++ 07_timestamps/src/_arch/aarch64/time.rs -@@ -0,0 +1,119 @@ +@@ -0,0 +1,121 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +// +// Copyright (c) 2018-2022 Andre Richter @@ -329,6 +329,7 @@ diff -uNr 06_uart_chainloader/src/_arch/aarch64/time.rs 07_timestamps/src/_arch/ + // Calculate the register compare value. + let frq = CNTFRQ_EL0.get(); + let x = match frq.checked_mul(duration.as_nanos() as u64) { ++ #[allow(unused_imports)] + None => { + warn!("Spin duration too long, skipping"); + return; @@ -347,6 +348,7 @@ diff -uNr 06_uart_chainloader/src/_arch/aarch64/time.rs 07_timestamps/src/_arch/ + None + }; + ++ #[allow(unused_imports)] + if let Some(w) = warn { + warn!( + "Spin duration {} than architecturally supported, skipping", @@ -630,10 +632,40 @@ diff -uNr 06_uart_chainloader/src/main.rs 07_timestamps/src/main.rs + } } +diff -uNr 06_uart_chainloader/src/panic_wait.rs 07_timestamps/src/panic_wait.rs +--- 06_uart_chainloader/src/panic_wait.rs ++++ 07_timestamps/src/panic_wait.rs +@@ -29,10 +29,23 @@ + + #[panic_handler] + fn panic(info: &PanicInfo) -> ! { ++ use crate::time::interface::TimeManager; ++ ++ let timestamp = crate::time::time_manager().uptime(); ++ + if let Some(args) = info.message() { +- panic_println!("\nKernel panic: {}", args); ++ panic_println!( ++ "[ {:>3}.{:06}] Kernel panic: {}", ++ timestamp.as_secs(), ++ timestamp.subsec_micros(), ++ args, ++ ); + } else { +- panic_println!("\nKernel panic!"); ++ panic_println!( ++ "[ {:>3}.{:06}] Kernel panic!", ++ timestamp.as_secs(), ++ timestamp.subsec_micros(), ++ ); + } + + cpu::wait_forever() + diff -uNr 06_uart_chainloader/src/print.rs 07_timestamps/src/print.rs --- 06_uart_chainloader/src/print.rs +++ 07_timestamps/src/print.rs -@@ -36,3 +36,71 @@ +@@ -36,3 +36,59 @@ $crate::print::_print(format_args_nl!($($arg)*)); }) } @@ -642,31 +674,25 @@ diff -uNr 06_uart_chainloader/src/print.rs 07_timestamps/src/print.rs +#[macro_export] +macro_rules! info { + ($string:expr) => ({ -+ #[allow(unused_imports)] -+ use crate::time::interface::TimeManager; ++ use $crate::time::interface::TimeManager; + + let timestamp = $crate::time::time_manager().uptime(); -+ let timestamp_subsec_us = timestamp.subsec_micros(); + + $crate::print::_print(format_args_nl!( -+ concat!("[ {:>3}.{:03}{:03}] ", $string), ++ concat!("[ {:>3}.{:06}] ", $string), + timestamp.as_secs(), -+ timestamp_subsec_us / 1_000, -+ timestamp_subsec_us modulo 1_000 ++ timestamp.subsec_micros(), + )); + }); + ($format_string:expr, $($arg:tt)*) => ({ -+ #[allow(unused_imports)] -+ use crate::time::interface::TimeManager; ++ use $crate::time::interface::TimeManager; + + let timestamp = $crate::time::time_manager().uptime(); -+ let timestamp_subsec_us = timestamp.subsec_micros(); + + $crate::print::_print(format_args_nl!( -+ concat!("[ {:>3}.{:03}{:03}] ", $format_string), ++ concat!("[ {:>3}.{:06}] ", $format_string), + timestamp.as_secs(), -+ timestamp_subsec_us / 1_000, -+ timestamp_subsec_us modulo 1_000, ++ timestamp.subsec_micros(), + $($arg)* + )); + }) @@ -676,31 +702,25 @@ diff -uNr 06_uart_chainloader/src/print.rs 07_timestamps/src/print.rs +#[macro_export] +macro_rules! warn { + ($string:expr) => ({ -+ #[allow(unused_imports)] -+ use crate::time::interface::TimeManager; ++ use $crate::time::interface::TimeManager; + + let timestamp = $crate::time::time_manager().uptime(); -+ let timestamp_subsec_us = timestamp.subsec_micros(); + + $crate::print::_print(format_args_nl!( -+ concat!("[W {:>3}.{:03}{:03}] ", $string), ++ concat!("[W {:>3}.{:06}] ", $string), + timestamp.as_secs(), -+ timestamp_subsec_us / 1_000, -+ timestamp_subsec_us modulo 1_000 ++ timestamp.subsec_micros(), + )); + }); + ($format_string:expr, $($arg:tt)*) => ({ -+ #[allow(unused_imports)] -+ use crate::time::interface::TimeManager; ++ use $crate::time::interface::TimeManager; + + let timestamp = $crate::time::time_manager().uptime(); -+ let timestamp_subsec_us = timestamp.subsec_micros(); + + $crate::print::_print(format_args_nl!( -+ concat!("[W {:>3}.{:03}{:03}] ", $format_string), ++ concat!("[W {:>3}.{:06}] ", $format_string), + timestamp.as_secs(), -+ timestamp_subsec_us / 1_000, -+ timestamp_subsec_us modulo 1_000, ++ timestamp.subsec_micros(), + $($arg)* + )); + }) diff --git a/07_timestamps/src/_arch/aarch64/time.rs b/07_timestamps/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/07_timestamps/src/_arch/aarch64/time.rs +++ b/07_timestamps/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/07_timestamps/src/panic_wait.rs b/07_timestamps/src/panic_wait.rs index 946041b3..923db329 100644 --- a/07_timestamps/src/panic_wait.rs +++ b/07_timestamps/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/07_timestamps/src/print.rs b/07_timestamps/src/print.rs index 5decb292..9ec13a28 100644 --- a/07_timestamps/src/print.rs +++ b/07_timestamps/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/08_hw_debug_JTAG/src/_arch/aarch64/time.rs b/08_hw_debug_JTAG/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/08_hw_debug_JTAG/src/_arch/aarch64/time.rs +++ b/08_hw_debug_JTAG/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/08_hw_debug_JTAG/src/panic_wait.rs b/08_hw_debug_JTAG/src/panic_wait.rs index 946041b3..923db329 100644 --- a/08_hw_debug_JTAG/src/panic_wait.rs +++ b/08_hw_debug_JTAG/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/08_hw_debug_JTAG/src/print.rs b/08_hw_debug_JTAG/src/print.rs index 5decb292..9ec13a28 100644 --- a/08_hw_debug_JTAG/src/print.rs +++ b/08_hw_debug_JTAG/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/09_privilege_level/src/_arch/aarch64/time.rs b/09_privilege_level/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/09_privilege_level/src/_arch/aarch64/time.rs +++ b/09_privilege_level/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/09_privilege_level/src/panic_wait.rs b/09_privilege_level/src/panic_wait.rs index 946041b3..923db329 100644 --- a/09_privilege_level/src/panic_wait.rs +++ b/09_privilege_level/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/09_privilege_level/src/print.rs b/09_privilege_level/src/print.rs index 5decb292..9ec13a28 100644 --- a/09_privilege_level/src/print.rs +++ b/09_privilege_level/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/10_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs b/10_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/10_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs +++ b/10_virtual_mem_part1_identity_mapping/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/10_virtual_mem_part1_identity_mapping/src/panic_wait.rs b/10_virtual_mem_part1_identity_mapping/src/panic_wait.rs index 946041b3..923db329 100644 --- a/10_virtual_mem_part1_identity_mapping/src/panic_wait.rs +++ b/10_virtual_mem_part1_identity_mapping/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/10_virtual_mem_part1_identity_mapping/src/print.rs b/10_virtual_mem_part1_identity_mapping/src/print.rs index 5decb292..9ec13a28 100644 --- a/10_virtual_mem_part1_identity_mapping/src/print.rs +++ b/10_virtual_mem_part1_identity_mapping/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/11_exceptions_part1_groundwork/src/_arch/aarch64/time.rs b/11_exceptions_part1_groundwork/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/11_exceptions_part1_groundwork/src/_arch/aarch64/time.rs +++ b/11_exceptions_part1_groundwork/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/11_exceptions_part1_groundwork/src/panic_wait.rs b/11_exceptions_part1_groundwork/src/panic_wait.rs index 946041b3..923db329 100644 --- a/11_exceptions_part1_groundwork/src/panic_wait.rs +++ b/11_exceptions_part1_groundwork/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/11_exceptions_part1_groundwork/src/print.rs b/11_exceptions_part1_groundwork/src/print.rs index 5decb292..9ec13a28 100644 --- a/11_exceptions_part1_groundwork/src/print.rs +++ b/11_exceptions_part1_groundwork/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/12_integrated_testing/README.md b/12_integrated_testing/README.md index 48fd1876..71ee3342 100644 --- a/12_integrated_testing/README.md +++ b/12_integrated_testing/README.md @@ -849,9 +849,8 @@ Compiling integration test(s) - rpi3 馃 Testing synchronous exception handling by causing a page fault ------------------------------------------------------------------- - Writing beyond mapped area to address 9 GiB... - - Kernel panic: + [ 0.163030] Writing beyond mapped area to address 9 GiB... + [ 0.164791] Kernel panic: CPU Exception! ESR_EL1: 0x96000004 @@ -1698,8 +1697,8 @@ diff -uNr 11_exceptions_part1_groundwork/src/panic_wait.rs 12_integrated_testing /// Prints with a newline - only use from the panic handler. /// /// Carbon copy from -@@ -35,5 +52,5 @@ - panic_println!("\nKernel panic!"); +@@ -48,5 +65,5 @@ + ); } - cpu::wait_forever() @@ -1929,7 +1928,7 @@ diff -uNr 11_exceptions_part1_groundwork/tests/02_exception_sync_page_fault.rs 1 +/// or indirectly. +mod panic_exit_success; + -+use libkernel::{bsp, cpu, exception, memory, println}; ++use libkernel::{bsp, cpu, exception, info, memory, println}; + +#[no_mangle] +unsafe fn kernel_init() -> ! { @@ -1942,11 +1941,11 @@ diff -uNr 11_exceptions_part1_groundwork/tests/02_exception_sync_page_fault.rs 1 + println!("Testing synchronous exception handling by causing a page fault"); + + if let Err(string) = memory::mmu::mmu().enable_mmu_and_caching() { -+ println!("MMU: {}", string); ++ info!("MMU: {}", string); + cpu::qemu_exit_failure() + } + -+ println!("Writing beyond mapped area to address 9 GiB..."); ++ 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 --git a/12_integrated_testing/src/_arch/aarch64/time.rs b/12_integrated_testing/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/12_integrated_testing/src/_arch/aarch64/time.rs +++ b/12_integrated_testing/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/12_integrated_testing/src/panic_wait.rs b/12_integrated_testing/src/panic_wait.rs index a20e37e1..2e56f1ce 100644 --- a/12_integrated_testing/src/panic_wait.rs +++ b/12_integrated_testing/src/panic_wait.rs @@ -46,10 +46,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } _panic_exit() diff --git a/12_integrated_testing/src/print.rs b/12_integrated_testing/src/print.rs index 5decb292..9ec13a28 100644 --- a/12_integrated_testing/src/print.rs +++ b/12_integrated_testing/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/12_integrated_testing/tests/02_exception_sync_page_fault.rs b/12_integrated_testing/tests/02_exception_sync_page_fault.rs index 1c4133e1..9be94acd 100644 --- a/12_integrated_testing/tests/02_exception_sync_page_fault.rs +++ b/12_integrated_testing/tests/02_exception_sync_page_fault.rs @@ -17,7 +17,7 @@ /// or indirectly. mod panic_exit_success; -use libkernel::{bsp, cpu, exception, memory, println}; +use libkernel::{bsp, cpu, exception, info, memory, println}; #[no_mangle] unsafe fn kernel_init() -> ! { @@ -30,11 +30,11 @@ unsafe fn kernel_init() -> ! { println!("Testing synchronous exception handling by causing a page fault"); if let Err(string) = memory::mmu::mmu().enable_mmu_and_caching() { - println!("MMU: {}", string); + info!("MMU: {}", string); cpu::qemu_exit_failure() } - println!("Writing beyond mapped area to address 9 GiB..."); + 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 --git a/13_exceptions_part2_peripheral_IRQs/README.md b/13_exceptions_part2_peripheral_IRQs/README.md index df20c15b..42b984b7 100644 --- a/13_exceptions_part2_peripheral_IRQs/README.md +++ b/13_exceptions_part2_peripheral_IRQs/README.md @@ -2511,15 +2511,15 @@ diff -uNr 12_integrated_testing/src/panic_wait.rs 13_exceptions_part2_peripheral use core::{fmt, panic::PanicInfo}; //-------------------------------------------------------------------------------------------------- -@@ -46,6 +46,8 @@ - - #[panic_handler] +@@ -48,6 +48,8 @@ fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + unsafe { exception::asynchronous::local_irq_mask() }; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); - } else { diff -uNr 12_integrated_testing/src/state.rs 13_exceptions_part2_peripheral_IRQs/src/state.rs --- 12_integrated_testing/src/state.rs diff --git a/13_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs b/13_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/13_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs +++ b/13_exceptions_part2_peripheral_IRQs/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/13_exceptions_part2_peripheral_IRQs/src/panic_wait.rs b/13_exceptions_part2_peripheral_IRQs/src/panic_wait.rs index 0f958f28..da7106c9 100644 --- a/13_exceptions_part2_peripheral_IRQs/src/panic_wait.rs +++ b/13_exceptions_part2_peripheral_IRQs/src/panic_wait.rs @@ -46,12 +46,25 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + unsafe { exception::asynchronous::local_irq_mask() }; + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } _panic_exit() diff --git a/13_exceptions_part2_peripheral_IRQs/src/print.rs b/13_exceptions_part2_peripheral_IRQs/src/print.rs index 5decb292..9ec13a28 100644 --- a/13_exceptions_part2_peripheral_IRQs/src/print.rs +++ b/13_exceptions_part2_peripheral_IRQs/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault.rs b/13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault.rs index 1c4133e1..9be94acd 100644 --- a/13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault.rs +++ b/13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault.rs @@ -17,7 +17,7 @@ /// or indirectly. mod panic_exit_success; -use libkernel::{bsp, cpu, exception, memory, println}; +use libkernel::{bsp, cpu, exception, info, memory, println}; #[no_mangle] unsafe fn kernel_init() -> ! { @@ -30,11 +30,11 @@ unsafe fn kernel_init() -> ! { println!("Testing synchronous exception handling by causing a page fault"); if let Err(string) = memory::mmu::mmu().enable_mmu_and_caching() { - println!("MMU: {}", string); + info!("MMU: {}", string); cpu::qemu_exit_failure() } - println!("Writing beyond mapped area to address 9 GiB..."); + 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 --git a/14_virtual_mem_part2_mmio_remap/README.md b/14_virtual_mem_part2_mmio_remap/README.md index 82fa51a2..3f6c78e9 100644 --- a/14_virtual_mem_part2_mmio_remap/README.md +++ b/14_virtual_mem_part2_mmio_remap/README.md @@ -3609,17 +3609,17 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault println!("Testing synchronous exception handling by causing a page fault"); - if let Err(string) = memory::mmu::mmu().enable_mmu_and_caching() { -- println!("MMU: {}", string); +- info!("MMU: {}", string); + let phys_kernel_tables_base_addr = match memory::mmu::kernel_map_binary() { + Err(string) => { -+ println!("Error mapping kernel binary: {}", string); ++ info!("Error mapping kernel binary: {}", string); + cpu::qemu_exit_failure() + } + Ok(addr) => addr, + }; + + if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) { -+ println!("Enabling MMU failed: {}", e); ++ 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. @@ -3638,7 +3638,7 @@ diff -uNr 13_exceptions_part2_peripheral_IRQs/tests/02_exception_sync_page_fault + bsp::driver::driver_manager().post_early_print_device_driver_init(); + // Printing available again from here on. - println!("Writing beyond mapped area to address 9 GiB..."); + info!("Writing beyond mapped area to address 9 GiB..."); let big_addr: u64 = 9 * 1024 * 1024 * 1024; ``` diff --git a/14_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs b/14_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/14_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs +++ b/14_virtual_mem_part2_mmio_remap/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/14_virtual_mem_part2_mmio_remap/src/panic_wait.rs b/14_virtual_mem_part2_mmio_remap/src/panic_wait.rs index 0f958f28..da7106c9 100644 --- a/14_virtual_mem_part2_mmio_remap/src/panic_wait.rs +++ b/14_virtual_mem_part2_mmio_remap/src/panic_wait.rs @@ -46,12 +46,25 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + unsafe { exception::asynchronous::local_irq_mask() }; + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } _panic_exit() diff --git a/14_virtual_mem_part2_mmio_remap/src/print.rs b/14_virtual_mem_part2_mmio_remap/src/print.rs index 5decb292..9ec13a28 100644 --- a/14_virtual_mem_part2_mmio_remap/src/print.rs +++ b/14_virtual_mem_part2_mmio_remap/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs b/14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs index de92b2b2..e146aa3e 100644 --- a/14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs +++ b/14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs @@ -17,7 +17,7 @@ /// or indirectly. mod panic_exit_success; -use libkernel::{bsp, cpu, exception, memory, println}; +use libkernel::{bsp, cpu, exception, info, memory, println}; #[no_mangle] unsafe fn kernel_init() -> ! { @@ -30,14 +30,14 @@ unsafe fn kernel_init() -> ! { let phys_kernel_tables_base_addr = match memory::mmu::kernel_map_binary() { Err(string) => { - println!("Error mapping kernel binary: {}", string); + info!("Error mapping kernel binary: {}", string); cpu::qemu_exit_failure() } Ok(addr) => addr, }; if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) { - println!("Enabling MMU failed: {}", e); + 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. @@ -56,7 +56,7 @@ unsafe fn kernel_init() -> ! { bsp::driver::driver_manager().post_early_print_device_driver_init(); // Printing available again from here on. - println!("Writing beyond mapped area to address 9 GiB..."); + 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 --git a/15_virtual_mem_part3_precomputed_tables/README.md b/15_virtual_mem_part3_precomputed_tables/README.md index b58ed67e..4d7cc40e 100644 --- a/15_virtual_mem_part3_precomputed_tables/README.md +++ b/15_virtual_mem_part3_precomputed_tables/README.md @@ -1739,14 +1739,14 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs - - let phys_kernel_tables_base_addr = match memory::mmu::kernel_map_binary() { - Err(string) => { -- println!("Error mapping kernel binary: {}", string); +- info!("Error mapping kernel binary: {}", string); - cpu::qemu_exit_failure() - } - Ok(addr) => addr, - }; - - if let Err(e) = memory::mmu::enable_mmu_and_caching(phys_kernel_tables_base_addr) { -- println!("Enabling MMU failed: {}", e); +- 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. @@ -1767,7 +1767,7 @@ diff -uNr 14_virtual_mem_part2_mmio_remap/tests/02_exception_sync_page_fault.rs + // This line will be printed as the test header. + println!("Testing synchronous exception handling by causing a page fault"); - println!("Writing beyond mapped area to address 9 GiB..."); + info!("Writing beyond mapped area to address 9 GiB..."); let big_addr: u64 = 9 * 1024 * 1024 * 1024; diff -uNr 14_virtual_mem_part2_mmio_remap/tests/03_exception_irq_sanity.rs 15_virtual_mem_part3_precomputed_tables/tests/03_exception_irq_sanity.rs diff --git a/15_virtual_mem_part3_precomputed_tables/src/_arch/aarch64/time.rs b/15_virtual_mem_part3_precomputed_tables/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/15_virtual_mem_part3_precomputed_tables/src/_arch/aarch64/time.rs +++ b/15_virtual_mem_part3_precomputed_tables/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/15_virtual_mem_part3_precomputed_tables/src/panic_wait.rs b/15_virtual_mem_part3_precomputed_tables/src/panic_wait.rs index 0f958f28..da7106c9 100644 --- a/15_virtual_mem_part3_precomputed_tables/src/panic_wait.rs +++ b/15_virtual_mem_part3_precomputed_tables/src/panic_wait.rs @@ -46,12 +46,25 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + unsafe { exception::asynchronous::local_irq_mask() }; + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } _panic_exit() diff --git a/15_virtual_mem_part3_precomputed_tables/src/print.rs b/15_virtual_mem_part3_precomputed_tables/src/print.rs index 5decb292..9ec13a28 100644 --- a/15_virtual_mem_part3_precomputed_tables/src/print.rs +++ b/15_virtual_mem_part3_precomputed_tables/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/15_virtual_mem_part3_precomputed_tables/tests/02_exception_sync_page_fault.rs b/15_virtual_mem_part3_precomputed_tables/tests/02_exception_sync_page_fault.rs index 2cf693fc..2d4b0977 100644 --- a/15_virtual_mem_part3_precomputed_tables/tests/02_exception_sync_page_fault.rs +++ b/15_virtual_mem_part3_precomputed_tables/tests/02_exception_sync_page_fault.rs @@ -17,7 +17,7 @@ /// or indirectly. mod panic_exit_success; -use libkernel::{bsp, cpu, exception, memory, println}; +use libkernel::{bsp, cpu, exception, info, memory, println}; #[no_mangle] unsafe fn kernel_init() -> ! { @@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! { // This line will be printed as the test header. println!("Testing synchronous exception handling by causing a page fault"); - println!("Writing beyond mapped area to address 9 GiB..."); + 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 --git a/16_virtual_mem_part4_higher_half_kernel/README.md b/16_virtual_mem_part4_higher_half_kernel/README.md index bde23439..487ce443 100644 --- a/16_virtual_mem_part4_higher_half_kernel/README.md +++ b/16_virtual_mem_part4_higher_half_kernel/README.md @@ -877,9 +877,9 @@ diff -uNr 15_virtual_mem_part3_precomputed_tables/tests/02_exception_sync_page_f // This line will be printed as the test header. println!("Testing synchronous exception handling by causing a page fault"); -- println!("Writing beyond mapped area to address 9 GiB..."); +- info!("Writing beyond mapped area to address 9 GiB..."); - let big_addr: u64 = 9 * 1024 * 1024 * 1024; -+ println!("Writing to bottom of address space to address 1 GiB..."); ++ info!("Writing to bottom of address space to address 1 GiB..."); + let big_addr: u64 = 1 * 1024 * 1024 * 1024; core::ptr::read_volatile(big_addr as *mut u64); diff --git a/16_virtual_mem_part4_higher_half_kernel/src/_arch/aarch64/time.rs b/16_virtual_mem_part4_higher_half_kernel/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/16_virtual_mem_part4_higher_half_kernel/src/_arch/aarch64/time.rs +++ b/16_virtual_mem_part4_higher_half_kernel/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/16_virtual_mem_part4_higher_half_kernel/src/panic_wait.rs b/16_virtual_mem_part4_higher_half_kernel/src/panic_wait.rs index 0f958f28..da7106c9 100644 --- a/16_virtual_mem_part4_higher_half_kernel/src/panic_wait.rs +++ b/16_virtual_mem_part4_higher_half_kernel/src/panic_wait.rs @@ -46,12 +46,25 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + unsafe { exception::asynchronous::local_irq_mask() }; + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } _panic_exit() diff --git a/16_virtual_mem_part4_higher_half_kernel/src/print.rs b/16_virtual_mem_part4_higher_half_kernel/src/print.rs index 5decb292..9ec13a28 100644 --- a/16_virtual_mem_part4_higher_half_kernel/src/print.rs +++ b/16_virtual_mem_part4_higher_half_kernel/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) diff --git a/16_virtual_mem_part4_higher_half_kernel/tests/02_exception_sync_page_fault.rs b/16_virtual_mem_part4_higher_half_kernel/tests/02_exception_sync_page_fault.rs index b2824615..71b63e21 100644 --- a/16_virtual_mem_part4_higher_half_kernel/tests/02_exception_sync_page_fault.rs +++ b/16_virtual_mem_part4_higher_half_kernel/tests/02_exception_sync_page_fault.rs @@ -17,7 +17,7 @@ /// or indirectly. mod panic_exit_success; -use libkernel::{bsp, cpu, exception, memory, println}; +use libkernel::{bsp, cpu, exception, info, memory, println}; #[no_mangle] unsafe fn kernel_init() -> ! { @@ -28,7 +28,7 @@ unsafe fn kernel_init() -> ! { // This line will be printed as the test header. println!("Testing synchronous exception handling by causing a page fault"); - println!("Writing to bottom of address space to address 1 GiB..."); + info!("Writing to bottom of address space to address 1 GiB..."); let big_addr: u64 = 1 * 1024 * 1024 * 1024; core::ptr::read_volatile(big_addr as *mut u64); diff --git a/X1_JTAG_boot/jtag_boot_rpi3.img b/X1_JTAG_boot/jtag_boot_rpi3.img index 752daff808a7e211ccd731e16780a081ca9ffbea..64189d659354f3894c8887bc419ede120173112f 100755 GIT binary patch delta 2195 zcmai#ZA?>F7{|}KmzLY2NTC8!gqBX)f>^a6=@vtQ#6ekR(z&QxHc{r%3S*{j?!!`B zblD)fh2tT**$*OH;;t{rmSRH9vcOo3WLcat-TbtobL(vt3^UOtD|gRn%Oun3Ne;K? z-t+SO{?Gq81l9-E_iw=;f4%i4USe0E0gTXBk(-DZ0{T!Jr^cMaKsWPyxt@y9CEkg( zJqBWd9yNU{MzXOO;Su?f)+jb{J%-Q$#V3lwo=Rfj1FqOOBGoA1Is}sq`buibc^OL~ zU(N>{Y(+2egbw81;&26he~Ghha0MBHx%^^Bq8*iAlbgBAbIm9r_yR6f>z+bh%SYSPm4i!}Tr;QwOj^&awheo_+)x~2fg!(Nf?BtFt-#ts}$qbLlbTt-t zo$qr=JW8mNt&#*=Um*4w7I~XR?ySOh{yGRlvn~Edm;L!Wss#1m@+8e(1UlAZG!z zRW)&J1^`b3a7^~gcc*QbIDwSW&p@l1b^-Cs8Vymc$kD|i;unB;x|$Q&!BHbh zSbS%K&J$)5Z{Wp)5QrIwQtFMZBTR+pMih3#`kvKB`ChpVf}*SDbtPoNd7Bcn3}^Fu@eK^%w;n$mg11 zZ??|uJb1+dX>%70&qfu$%=QYASu;37fV9!B{1u9n()37v<>FW1C;@%yavwwC&2%E) zs42r}0AX~F1&9XiWF<}J7w0yvBoL`qfR{qgN@^^q+zLv?K&42wQe^aoNDYYqb<~t4 zwlEb;3NfXQp@ztQPLzyTlprONkr&_lI~}MzjxW#IP-3A?Ta;;=9zajFX$XN$QQD^U zkFzO$)TRdOLz@;Xuqj|b^^(ZvnA{joS+xSZ%7az2#Hf{7RU!V7l#dP~RJTpfUzKIK z=sYD_ZRx_y!OHJ589>O9xIo9W1^&r7xkw&|>TE-admGg$*P7>Dt3|_VaJds)F8I_z z0i5cA+<72x668${IqZYnwfZK4YH;)^aBwZlVTD@v1)PLbXxIa$je@MLVAdG8-vy4p z2WIu`6N3>W@{0p37x00(Rr(7NR>RugPkLDeL>o{z3hwr?cV?TNG~d0 zSFWcoF3tC=a|13vEb$kjaCLjY&5|0_Ci|Pg@`Fl{L*QZVvUEe$aIJTJJaF6>^m2*@1XXjHvbdR*v$xN>58zC zHb7+e0^BPkX3YkdJ&INfXp#Gmxhh82z*Vu9OaXo&M8QfPC*{!TLIb8h6}4;Hi=j>z zv<Jc5nft+IVSt3{{_M*E8SqGUG&MTt%l!tcItpcGE_kNu5=c-cwsdy}EVzqb2E~ zyDa^TmeBLMGR2re^swv1&^n0D$T1xamhBUq}xl18o}tP_OyT|=GSKC WyO*cA@xOanX?FjGy delta 2143 zcmb7FdrVtZ7(e%3N^i?+6b6j)Xaj?`DD1@maiMILb< zL5Xra#7%0lu|?Uz5w;Z~)u>GVnNznZ8|q&c(AWoWA6t!Z{Z8A(&A6y1IrN@$zWd$Z zJEfve#rOm8-E{aG3q02p1rSxdUF%dU8pA%tPE&mo4T+ z9#WCZ0w!JYKl0}_f5`_RV74$V+CEEymd)dKUXThOGffnx8$% z;pX%4xJvO^w-TXFQ%@P5gZ(*Ng6Ca4wl7#XJX<8EemM#nma4`~wlAEq5ZF<97oM*W zscETttP=oMt&UUg{h-~vE%t;p2F@2M6m;Jer@7G9?`*DLhxb`dS*J%idTHsgu@;E` z(iZ0gK|A%f0VfEG`(Z!e;^`^3s1A&B*pq|sqy^cre#tuKFG0b8OQ601FHALzJmh017E#HYw0x zvrXZg1-7xE%nT5{1WKF+WttQhyO}z3#18U+6f+-kl(Azn&4Mh9<=g;I6W{|YU>fwX z>S;hcmzacS2LNah3Myc~8rZKmQHG~KiJ~o_Ml)j%O6&#p=Kz?=cG{`e>hNjUkAwKO zeo<`#!u=C@n5pBpKaSk5K;UApoHCibOaTkR^Y2Gf4|wO_j)IdQm;ap>(T}U zFY+)2m`Jk`Z$`z~GE$5uPV#uWBpuNp&D9v=cTgKYE!J`|0Sgya>LOF>o!gaK$)xiC zCJhxra`s{a6jc?GsqU49v?p6td2w4Isfdo68@iEu3pu39N&FR|F2tcB1_d22!)c^n zl@|YeAqGszB5aE13(1%&uLkt;3kZAU(UkGkYSv)S76d&MMeheV{(Ko_I_m3-uw>_{ zFNdQ(fy2HWfm;3uBa#GYiED1T<8v^f(mDz&lDiq z1eTh>%1dCeuL3NC0@vFPHU+-dw*H>$I_IX5m~pN1285ud+6+M*&;cem@TpPIG!(D)388BQd!{%%34BEGe7Z5*n$|V2LYxM#!{elX=vRDxkJSqCH8CsDh!I`gs zqwP@+a~p4T>sBVOZ{v~s*c-^*2YHzNZEqrXFFdooWANNSYEts;OpAui*~7Xzhq>`^ z_OQ=_aMP#R!>pPcAOo}62mKxLW}+0cs+R0gV6{NKIe-Svy-)^|qX<6(GB~3Dl7%5> zWxFNIcwDq0t^$8^}UNExD2z zOCE)($x0(DGLzXeClGB`328{zt^L2>@{+UZ`N}gXVMHS-WHNoD>H&3l*%0CRw3-;y zS&1W&?UV?vaZ;ns&bSfTg$4|bm*Fqmk7$=hQ%E}18_F~hy8o4aZX|x)o#>Jq>NR{_ zCNX3@SO0Bh7;0kptj&r2fl J9CmgfDG08DvN``XFa^x>PtHc|y=D~I)&PC+6<(!mah9|~C~yH`!w zp{hA^) zldHAPv+j{q+ zb^c659iNTAyT|ID*7b?tHkf(yo6*R@?dRj8A6-gY%pXTAKYSNo^FgV3{lucy1#_CN z-)Y%TchG`JXs!iRZ4GDv4dBfKBNwDYBkMCMI=SQGFTX4wJQjUVBAJf?Fvy5%Kk6aS_@JoOzepL+5ZPcJT%{E zRyp8E6Ad9?9-;C+pxT9Ps&)WMI4LRbd_B$e3iQ@#LJw`|6O#b##}si%*L7DD+6pMY zVt-SR^icuz^TCIXQV}=3%ENRSgPy>?l$~@DdyYTg&Otwo;5iVu%I&D1KKi#lkpsBe z!~NlGIflc<+~s`reE+qZ*=jpp*o){U^&lb_d<35@U~LH1e4@&clly3HKhO^_BmeUP zxv|j(r3WW1WM*e-_a%y0-hM3a%4wjtGeB1Ypz<>;@$CRnL&Mk85)RpA95UX%n4fOP z$BkzjX|ba`RNagHh_Mn7)h4gx*6N^izmt|ZT;gkJm*23t#E(=e414J^#{8H$S0@rSSs$$(bYPhtkO4VU>v)RD zsa=)x&zu$grD0F8n6r`m#YUZ{5`(VF-A*IEtb@2-Q@W4G2adm`48{ifdY@J{+g@o_ zuEb%JxLh-AYz3DoBd^`Cu`XP;#Q9-s;N+ITJBCfzbi*-XW;^8on{TjN6(ga@4!hnE z9+TPkuGW`dH7K0M<$z)1jB*)@_XggM^$oPfhq#?G?y<{UKE-b}t|N-l%7P6~?%9I- SAKGtacDdmM$8xc#to#FRE6Ke8 delta 1214 zcmaJ=UuaWT82`?_Nt@iH)~0Fx&gI_KT2rCwV%N>;8mcgCUnJ;*RA^&RTdh?iY%s`@ zjImJ`Mh-{lL-x>h58L$*R-({OVTywIq*CkVlc~PM#1>m0G-7-G?jN!9VFxbX`TqRA z^Eu*;o9xT-wQA)=;*` zG*v|;8cf%-dh-E}NcnHfznEQV9}V)UNa+U94UmdtutXAl%x~LE?D>kHx*^nQuTera`W%F zSOu4!@<0WEY)=$up&8^6Y+}V+%R(nDZy>UghVDb({a6L$$#n{gH7dFYBBns&PrK;DEeT4oQ{6Yh??H zm4(zA%AxH7KjqQJ3Vu3^HBr<{1o6JYb35-XcR)oiZlY;S0D;SzKh{Kh-zcL6fXm-$ z0649JGy;-WZRphYQ7^mYXeR-tI09=$TG#>f55ySY;`cccoxtwDu zK0S~Sk~wQ46;X$zd-fA*!6ripD22?j<-FCu*jODb@;C&cs`rol1Rt3v)UFB)?;p9a zq~BH7&=5TQu`W0S=qzGNh*9`UjO2_e8XHS{~e9#nG0ns?{N8$Ki6 zey<*X)u7t}!x!0ttCw-241yc{Dhu^@!^9*;)&?+U`!HVwOg;NHR}G8 z-zo~5KFD_(K4A|%hq(zi>+-hl{?`b)j3)Djk5i_tQ}NiwW6{Ck*7zySUu|5>X5@cD zi?0N|qS&g2*j4YA?ds-pqY$S`TOEdvznHc@ROp@mDckJnV_~12{pwlEc6*#??JVmP F-vSWza>W1u diff --git a/X1_JTAG_boot/src/_arch/aarch64/time.rs b/X1_JTAG_boot/src/_arch/aarch64/time.rs index 57624839..c814219c 100644 --- a/X1_JTAG_boot/src/_arch/aarch64/time.rs +++ b/X1_JTAG_boot/src/_arch/aarch64/time.rs @@ -78,6 +78,7 @@ impl time::interface::TimeManager for GenericTimer { // Calculate the register compare value. let frq = CNTFRQ_EL0.get(); let x = match frq.checked_mul(duration.as_nanos() as u64) { + #[allow(unused_imports)] None => { warn!("Spin duration too long, skipping"); return; @@ -96,6 +97,7 @@ impl time::interface::TimeManager for GenericTimer { None }; + #[allow(unused_imports)] if let Some(w) = warn { warn!( "Spin duration {} than architecturally supported, skipping", diff --git a/X1_JTAG_boot/src/panic_wait.rs b/X1_JTAG_boot/src/panic_wait.rs index 946041b3..923db329 100644 --- a/X1_JTAG_boot/src/panic_wait.rs +++ b/X1_JTAG_boot/src/panic_wait.rs @@ -29,10 +29,23 @@ macro_rules! panic_println { #[panic_handler] fn panic(info: &PanicInfo) -> ! { + use crate::time::interface::TimeManager; + + let timestamp = crate::time::time_manager().uptime(); + if let Some(args) = info.message() { - panic_println!("\nKernel panic: {}", args); + panic_println!( + "[ {:>3}.{:06}] Kernel panic: {}", + timestamp.as_secs(), + timestamp.subsec_micros(), + args, + ); } else { - panic_println!("\nKernel panic!"); + panic_println!( + "[ {:>3}.{:06}] Kernel panic!", + timestamp.as_secs(), + timestamp.subsec_micros(), + ); } cpu::wait_forever() diff --git a/X1_JTAG_boot/src/print.rs b/X1_JTAG_boot/src/print.rs index 5decb292..9ec13a28 100644 --- a/X1_JTAG_boot/src/print.rs +++ b/X1_JTAG_boot/src/print.rs @@ -41,31 +41,25 @@ macro_rules! println { #[macro_export] macro_rules! info { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $string), + concat!("[ {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[ {:>3}.{:03}{:03}] ", $format_string), + concat!("[ {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) @@ -75,31 +69,25 @@ macro_rules! info { #[macro_export] macro_rules! warn { ($string:expr) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $string), + concat!("[W {:>3}.{:06}] ", $string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000 + timestamp.subsec_micros(), )); }); ($format_string:expr, $($arg:tt)*) => ({ - #[allow(unused_imports)] - use crate::time::interface::TimeManager; + use $crate::time::interface::TimeManager; let timestamp = $crate::time::time_manager().uptime(); - let timestamp_subsec_us = timestamp.subsec_micros(); $crate::print::_print(format_args_nl!( - concat!("[W {:>3}.{:03}{:03}] ", $format_string), + concat!("[W {:>3}.{:06}] ", $format_string), timestamp.as_secs(), - timestamp_subsec_us / 1_000, - timestamp_subsec_us % 1_000, + timestamp.subsec_micros(), $($arg)* )); }) From a6be5b34ad621ab9425bb0b8913f99fcc525eba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=B0=7Ezanez?= <51524324+zanezhub@users.noreply.github.com> Date: Fri, 1 Apr 2022 01:14:44 -0600 Subject: [PATCH 2/2] README.ES.md -> 01 & 02 (#150) * README.ES.md I added a spanish translation for the README.md file, and modified the README.md to add my github profile and to add the link to README.ES.md file * Slightly reorganize translation overview * README.ES.md These changes are in response to PR comments * Update README.ES.md * README.ES.md -> 00_before_we_start * Updating README.ES.md I corrected a few mistakes in both README.ES.md files. * README.ES.md for 00 These changes are in response to PR comments * README.ES.md -> 01_wait_forever * README.ES.md -> 02_runtime_init * README.md for 01 & 02 with corrections/improvements * Update 01_wait_forever/README.ES.md * Update 02_runtime_init/README.ES.md Co-authored-by: zanez Co-authored-by: Andre Richter Co-authored-by: Diego Barrios Romero --- 01_wait_forever/README.ES.md | 55 ++++++ 02_runtime_init/README.ES.md | 348 +++++++++++++++++++++++++++++++++++ 2 files changed, 403 insertions(+) create mode 100644 01_wait_forever/README.ES.md create mode 100644 02_runtime_init/README.ES.md diff --git a/01_wait_forever/README.ES.md b/01_wait_forever/README.ES.md new file mode 100644 index 00000000..5244372a --- /dev/null +++ b/01_wait_forever/README.ES.md @@ -0,0 +1,55 @@ +# Tutorial 01 - Esperar infinitamente + +## tl;dr + +* Se configura la estructura que tiene el proyecto. + +* Se ejecuta una peque帽o c贸digo hecho en ensamblador que tiene como funci贸n detener todos los n煤cleos del procesador que est谩n ejecutando el kernel. + +## Compilar + +* El archivo `Makefile` permite ejecutar: + + * `doc`: Genera la documentaci贸n. + + * `qemu`: Ejecutar el kernel en QEMU. + + * `clippy`: Analiza el c贸digo y sugiere mejoras. + + * `clean`: Elimina todos los archivos generados durante la compilaci贸n, etc. + + * `readelf`: Inspecciona el archivo `ELF` de salida. + + * `objdump`: Inspecciona el ensamblador. + + * `nm`: Inspecciona los s铆mbolos. + +## C贸digo a revisar + +* El script para enlazado espec铆fico para la `BSP` llamado `link.ld`. + + * Carga la direcci贸n en `0x8_0000`. + + * Solo la secci贸n `.text`. + +* `main.rs`: [Atributos internos](https://doc.rust-lang.org/reference/attributes.html) importantes: + + * `#![no_std]`, `#![no_main]`. + +* `boot.s`: La funci贸n de ensamblador `_start()` que inicia `wfe` (Wait For Event / Esperar Hasta Un Evento), detiene todos los n煤cleos del procesador que est谩n ejecutando `_start()`. + +* Tenemos que definir una funci贸n que funcione como `#[panic_handler]` (manejador de p谩nico) para que el compilador no nos cause problemas. + + * Hazla `unimplemented!()` porque se eliminar谩 ya que no est谩 siendo usada. + +## Pru茅balo + +Dentro de la carpeta del proyecto, ejecuta a QEMU y mira el n煤cleo del procesador ejecutando `wfe` en bucle: + +``` +$ make qemu +[...] +IN: +0x00080000: d503205f wfe +0x00080004: 17ffffff b #0x80000 +``` diff --git a/02_runtime_init/README.ES.md b/02_runtime_init/README.ES.md new file mode 100644 index 00000000..6a5b3974 --- /dev/null +++ b/02_runtime_init/README.ES.md @@ -0,0 +1,348 @@ +# Tutorial 02 - Inicializaci贸n del `runtime` + +## tl;dr + +* Extendimos la funcionalidad de `boot.s` para que sea capaz de llamar c贸digo Rust por primera vez. Antes de que el cambio a Rust ocurra, se realizan algunos trabajos de inicializaci贸n del `runtime` (soporte para ejecuci贸n de c贸digo). +* El c贸digo Rust que es llamado solo pausa la ejecuci贸n con una llamada a `panic!()`. +* Ejecuta `make qemu` de nuevo para que puedas ver el c贸digo adicional en acci贸n. + +## Adiciones importantes + +* Adiciones importantes al script `link.ld`: + + * Nuevas secciones: `.rodata`, `.got`, `.data`, `.bss`. + + * Un lugar totalmente dedicado a enlazar argumentos de tiempo de arranque (boot-time) que necesitan estar listos cuando se llame a `_start()`. + +* `_start()` en `_arch/__arch_name__/cpu/boot.s`: + + 1. Para todos los n煤cleos expecto el n煤cleo 0. + + 2. Inicializa la [`DRAM`](https://es.wikipedia.org/wiki/DRAM) poniendo a cero la secci贸n [`.bss`](https://en.wikipedia.org/wiki/.bss). + + 3. Configura el `stack pointer` (puntero a la memoria [pila](https://es.wikipedia.org/wiki/Pila_(inform%C3%A1tica))). + + 4. Salta hacia la funci贸n `_start_rust()`, definida en `arch/__arch_name__/cpu/boot.rs`. + +* `_start_rust()`: + + * Llama a `kernel_init()`, que llama a `panic!()`, que al final tambi茅n pone al n煤cleo 0 en pausa. + +* La librer铆a ahora usa el crate [cortex-a](https://github.com/rust-embedded/cortex-a), que nos da abstracciones sin coste y envuelve las partes que hacen uso de un `unsafe` (partes con c贸digo que no es seguro y podr铆a causar errores) cuando se trabaja directamente con los recursos del procesador. + + * Lo puedes ver en acci贸n en `_arch/__arch_name__/cpu.rs`. + +## Diferencia con el archivo anterior + +```diff +diff -uNr 01_wait_forever/Cargo.toml 02_runtime_init/Cargo.toml +--- 01_wait_forever/Cargo.toml ++++ 02_runtime_init/Cargo.toml +@@ -1,6 +1,6 @@ + [package] + name = "mingo" +-version = "0.1.0" ++version = "0.2.0" + authors = ["Andre Richter "] + edition = "2021" + +@@ -21,3 +21,7 @@ + ##-------------------------------------------------------------------------------------------------- + + [dependencies] ++ ++# Platform specific dependencies ++[target.'cfg(target_arch = "aarch64")'.dependencies] ++cortex-a = { version = "7.x.x" } + +diff -uNr 01_wait_forever/Makefile 02_runtime_init/Makefile +--- 01_wait_forever/Makefile ++++ 02_runtime_init/Makefile +@@ -153,6 +153,8 @@ + $(call colorecho, "\nLaunching objdump") + @$(DOCKER_TOOLS) $(OBJDUMP_BINARY) --disassemble --demangle \ + --section .text \ ++ --section .rodata \ ++ --section .got \ + $(KERNEL_ELF) | rustfilt + + ##------------------------------------------------------------------------------ + +diff -uNr 01_wait_forever/src/_arch/aarch64/cpu/boot.rs 02_runtime_init/src/_arch/aarch64/cpu/boot.rs +--- 01_wait_forever/src/_arch/aarch64/cpu/boot.rs ++++ 02_runtime_init/src/_arch/aarch64/cpu/boot.rs +@@ -13,3 +13,15 @@ + + // Assembly counterpart to this file. + core::arch::global_asm!(include_str!("boot.s")); ++ ++//-------------------------------------------------------------------------------------------------- ++// Public Code ++//-------------------------------------------------------------------------------------------------- ++ ++/// The Rust entry of the `kernel` binary. ++/// ++/// The function is called from the assembly `_start` function. ++#[no_mangle] ++pub unsafe fn _start_rust() -> ! { ++ crate::kernel_init() ++} + +diff -uNr 01_wait_forever/src/_arch/aarch64/cpu/boot.s 02_runtime_init/src/_arch/aarch64/cpu/boot.s +--- 01_wait_forever/src/_arch/aarch64/cpu/boot.s ++++ 02_runtime_init/src/_arch/aarch64/cpu/boot.s +@@ -3,6 +3,24 @@ + // Copyright (c) 2021-2022 Andre Richter + + //-------------------------------------------------------------------------------------------------- ++// Definitions ++//-------------------------------------------------------------------------------------------------- ++ ++// Load the address of a symbol into a register, PC-relative. ++// ++// The symbol must lie within +/- 4 GiB of the Program Counter. ++// ++// # Resources ++// ++// - https://sourceware.org/binutils/docs-2.36/as/AArch64_002dRelocations.html ++.macro ADR_REL register, symbol ++ adrp \register, \symbol ++ add \register, \register, #:lo12:\symbol ++.endm ++ ++.equ _core_id_mask, 0b11 ++ ++//-------------------------------------------------------------------------------------------------- + // Public Code + //-------------------------------------------------------------------------------------------------- + .section .text._start +@@ -11,6 +29,34 @@ + // fn _start() + //------------------------------------------------------------------------------ + _start: ++ // Only proceed on the boot core. Park it otherwise. ++ mrs x1, MPIDR_EL1 ++ and x1, x1, _core_id_mask ++ ldr x2, BOOT_CORE_ID // provided by bsp/__board_name__/cpu.rs ++ cmp x1, x2 ++ b.ne .L_parking_loop ++ ++ // If execution reaches here, it is the boot core. ++ ++ // Initialize DRAM. ++ ADR_REL x0, __bss_start ++ ADR_REL x1, __bss_end_exclusive ++ ++.L_bss_init_loop: ++ cmp x0, x1 ++ b.eq .L_prepare_rust ++ stp xzr, xzr, [x0], #16 ++ b .L_bss_init_loop ++ ++ // Prepare the jump to Rust code. ++.L_prepare_rust: ++ // Set the stack pointer. ++ ADR_REL x0, __boot_core_stack_end_exclusive ++ mov sp, x0 ++ ++ // Jump to Rust code. ++ b _start_rust ++ + // Infinitely wait for events (aka "park the core"). + .L_parking_loop: + wfe + +diff -uNr 01_wait_forever/src/_arch/aarch64/cpu.rs 02_runtime_init/src/_arch/aarch64/cpu.rs +--- 01_wait_forever/src/_arch/aarch64/cpu.rs ++++ 02_runtime_init/src/_arch/aarch64/cpu.rs +@@ -0,0 +1,26 @@ ++// SPDX-License-Identifier: MIT OR Apache-2.0 ++// ++// Copyright (c) 2018-2022 Andre Richter ++ ++//! Architectural processor code. ++//! ++//! # Orientation ++//! ++//! Since arch modules are imported into generic modules using the path attribute, the path of this ++//! file is: ++//! ++//! crate::cpu::arch_cpu ++ ++use cortex_a::asm; ++ ++//-------------------------------------------------------------------------------------------------- ++// Public Code ++//-------------------------------------------------------------------------------------------------- ++ ++/// Pause execution on the core. ++#[inline(always)] ++pub fn wait_forever() -> ! { ++ loop { ++ asm::wfe() ++ } ++} + +diff -uNr 01_wait_forever/src/bsp/raspberrypi/cpu.rs 02_runtime_init/src/bsp/raspberrypi/cpu.rs +--- 01_wait_forever/src/bsp/raspberrypi/cpu.rs ++++ 02_runtime_init/src/bsp/raspberrypi/cpu.rs +@@ -0,0 +1,14 @@ ++// SPDX-License-Identifier: MIT OR Apache-2.0 ++// ++// Copyright (c) 2018-2022 Andre Richter ++ ++//! BSP Processor code. ++ ++//-------------------------------------------------------------------------------------------------- ++// Public Definitions ++//-------------------------------------------------------------------------------------------------- ++ ++/// Used by `arch` code to find the early boot core. ++#[no_mangle] ++#[link_section = ".text._start_arguments"] ++pub static BOOT_CORE_ID: u64 = 0; + +diff -uNr 01_wait_forever/src/bsp/raspberrypi/link.ld 02_runtime_init/src/bsp/raspberrypi/link.ld +--- 01_wait_forever/src/bsp/raspberrypi/link.ld ++++ 02_runtime_init/src/bsp/raspberrypi/link.ld +@@ -3,6 +3,8 @@ + * Copyright (c) 2018-2022 Andre Richter + */ + ++__rpi_phys_dram_start_addr = 0; ++ + /* The physical address at which the the kernel binary will be loaded by the Raspberry's firmware */ + __rpi_phys_binary_load_addr = 0x80000; + +@@ -13,21 +15,58 @@ + * 4 == R + * 5 == RX + * 6 == RW ++ * ++ * Segments are marked PT_LOAD below so that the ELF file provides virtual and physical addresses. ++ * It doesn't mean all of them need actually be loaded. + */ + PHDRS + { +- segment_code PT_LOAD FLAGS(5); ++ segment_boot_core_stack PT_LOAD FLAGS(6); ++ segment_code PT_LOAD FLAGS(5); ++ segment_data PT_LOAD FLAGS(6); + } + + SECTIONS + { +- . = __rpi_phys_binary_load_addr; ++ . = __rpi_phys_dram_start_addr; ++ ++ /*********************************************************************************************** ++ * Boot Core Stack ++ ***********************************************************************************************/ ++ .boot_core_stack (NOLOAD) : ++ { ++ /* ^ */ ++ /* | stack */ ++ . += __rpi_phys_binary_load_addr; /* | growth */ ++ /* | direction */ ++ __boot_core_stack_end_exclusive = .; /* | */ ++ } :segment_boot_core_stack + + /*********************************************************************************************** +- * Code ++ * Code + RO Data + Global Offset Table + ***********************************************************************************************/ + .text : + { + KEEP(*(.text._start)) ++ *(.text._start_arguments) /* Constants (or statics in Rust speak) read by _start(). */ ++ *(.text._start_rust) /* The Rust entry point */ ++ *(.text*) /* Everything else */ + } :segment_code ++ ++ .rodata : ALIGN(8) { *(.rodata*) } :segment_code ++ .got : ALIGN(8) { *(.got) } :segment_code ++ ++ /*********************************************************************************************** ++ * Data + BSS ++ ***********************************************************************************************/ ++ .data : { *(.data*) } :segment_data ++ ++ /* Section is zeroed in pairs of u64. Align start and end to 16 bytes */ ++ .bss (NOLOAD) : ALIGN(16) ++ { ++ __bss_start = .; ++ *(.bss*); ++ . = ALIGN(16); ++ __bss_end_exclusive = .; ++ } :segment_data + } + +diff -uNr 01_wait_forever/src/bsp/raspberrypi.rs 02_runtime_init/src/bsp/raspberrypi.rs +--- 01_wait_forever/src/bsp/raspberrypi.rs ++++ 02_runtime_init/src/bsp/raspberrypi.rs +@@ -4,4 +4,4 @@ + + //! Top-level BSP file for the Raspberry Pi 3 and 4. + +-// Coming soon. ++pub mod cpu; + +diff -uNr 01_wait_forever/src/cpu.rs 02_runtime_init/src/cpu.rs +--- 01_wait_forever/src/cpu.rs ++++ 02_runtime_init/src/cpu.rs +@@ -4,4 +4,13 @@ + + //! Processor code. + ++#[cfg(target_arch = "aarch64")] ++#[path = "_arch/aarch64/cpu.rs"] ++mod arch_cpu; ++ + mod boot; ++ ++//-------------------------------------------------------------------------------------------------- ++// Architectural Public Reexports ++//-------------------------------------------------------------------------------------------------- ++pub use arch_cpu::wait_forever; + +diff -uNr 01_wait_forever/src/main.rs 02_runtime_init/src/main.rs +--- 01_wait_forever/src/main.rs ++++ 02_runtime_init/src/main.rs +@@ -102,6 +102,7 @@ + //! + //! 1. The kernel's entry point is the function `cpu::boot::arch_boot::_start()`. + //! - It is implemented in `src/_arch/__arch_name__/cpu/boot.s`. ++//! 2. Once finished with architectural setup, the arch code calls `kernel_init()`. + + #![no_main] + #![no_std] +@@ -110,4 +111,11 @@ + mod cpu; + mod panic_wait; + +-// Kernel code coming next tutorial. ++/// Early init code. ++/// ++/// # Safety ++/// ++/// - Only a single core must be active and running this function. ++unsafe fn kernel_init() -> ! { ++ panic!() ++} + +diff -uNr 01_wait_forever/src/panic_wait.rs 02_runtime_init/src/panic_wait.rs +--- 01_wait_forever/src/panic_wait.rs ++++ 02_runtime_init/src/panic_wait.rs +@@ -4,9 +4,10 @@ + + //! A panic handler that infinitely waits. + ++use crate::cpu; + use core::panic::PanicInfo; + + #[panic_handler] + fn panic(_info: &PanicInfo) -> ! { +- unimplemented!() ++ cpu::wait_forever() + } +```