summaryrefslogtreecommitdiffstats
path: root/rsnix/src/gop.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rsnix/src/gop.rs')
-rw-r--r--rsnix/src/gop.rs21
1 files changed, 21 insertions, 0 deletions
diff --git a/rsnix/src/gop.rs b/rsnix/src/gop.rs
index 7b97d14..90c24bf 100644
--- a/rsnix/src/gop.rs
+++ b/rsnix/src/gop.rs
@@ -71,6 +71,20 @@ pub fn framebuffer_region() -> Option<(usize, usize)> {
71static mut SHADOW: *mut u32 = core::ptr::null_mut(); 71static mut SHADOW: *mut u32 = core::ptr::null_mut();
72static mut SHADOW_WORDS: usize = 0; 72static mut SHADOW_WORDS: usize = 0;
73 73
74/// Last boot-progress stage (set by `boot_marker`); the panic handler
75/// appends it to the on-screen band so a crash shows where boot died.
76static mut LAST_BOOT_STAGE: [u8; 96] = [0; 96];
77static mut LAST_BOOT_STAGE_LEN: usize = 0;
78const STAGE_MAX: usize = 96;
79
80/// The last boot stage string (for the panic band).
81pub fn last_boot_stage() -> alloc::string::String {
82 unsafe {
83 alloc::string::String::from_utf8_lossy(&LAST_BOOT_STAGE[..LAST_BOOT_STAGE_LEN])
84 .into_owned()
85 }
86}
87
74/// Diagnostic: when > 0, every display store busy-waits ~this many 88/// Diagnostic: when > 0, every display store busy-waits ~this many
75/// cycles first, simulating the per-write bus cost of an uncached real 89/// cycles first, simulating the per-write bus cost of an uncached real
76/// GOP framebuffer (QEMU's framebuffer is RAM — instant). Lets us 90/// GOP framebuffer (QEMU's framebuffer is RAM — instant). Lets us
@@ -338,6 +352,13 @@ pub fn init_shadow() {
338/// direct-display glyph path (the shadow may not exist yet in early 352/// direct-display glyph path (the shadow may not exist yet in early
339/// boot); the shell banner overwrites row 0 at first paint. 353/// boot); the shell banner overwrites row 0 at first paint.
340pub fn boot_marker(msg: &str) { 354pub fn boot_marker(msg: &str) {
355 // Record the stage so a later panic band can show how far boot got.
356 unsafe {
357 let n = msg.len().min(STAGE_MAX);
358 let dst = core::ptr::addr_of_mut!(LAST_BOOT_STAGE) as *mut u8;
359 core::ptr::copy_nonoverlapping(msg.as_ptr(), dst, n);
360 LAST_BOOT_STAGE_LEN = n;
361 }
341 let Some(fb) = fb().as_ref() else { 362 let Some(fb) = fb().as_ref() else {
342 return; 363 return;
343 }; 364 };