summaryrefslogtreecommitdiffstats
path: root/rsnix
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rsnix/src/vt.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs
index 4578f6c..6343b78 100644
--- a/rsnix/src/vt.rs
+++ b/rsnix/src/vt.rs
@@ -138,6 +138,48 @@ pub fn size() -> (usize, usize) {
138 unsafe { (ROWS, COLS) } 138 unsafe { (ROWS, COLS) }
139} 139}
140 140
141/// Shell-entry self-check: dump the vt grid's heap structs so a real-
142/// hardware boot shows whether the cells VecData / data arrays are sane
143/// at shell entry (the OptiPlex's first banner write #GPs when the
144/// cells buffer holds firmware 0xAA fill instead of real pointers).
145pub fn debug_verify() {
146 unsafe {
147 let total = ROWS * COLS;
148 let msg = |m: &str| {
149 crate::serial_println!("vt: {}", m);
150 };
151 if CELLS.is_null() || RENDERED.is_null() {
152 msg("verify: cells/renderd NULL — vt::init did not run");
153 return;
154 }
155 let c = &*(CELLS as *const Vec<Cell>);
156 let r = &*(RENDERED as *const Vec<Cell>);
157 msg(&alloc::format!(
158 "verify: cells ptr={:#x} cap={:#x} len={:#x} rendered ptr={:#x} cap={:#x} len={:#x} want={:#x}",
159 c.as_ptr() as usize,
160 c.capacity(),
161 c.len(),
162 r.as_ptr() as usize,
163 r.capacity(),
164 r.len(),
165 total
166 ));
167 // The cells array must cover rows*cols and be inside the heap.
168 let heap_ok = crate::memory::heap_range()
169 .map(|(hs, he)| {
170 let p = c.as_ptr() as usize;
171 let bytes = c.capacity().saturating_mul(core::mem::size_of::<Cell>());
172 p >= hs && p + bytes <= he
173 })
174 .unwrap_or(false);
175 if c.len() != total || r.len() != total || !heap_ok {
176 msg("verify: FAILED — cells/rendered not sane at shell entry");
177 } else {
178 msg("verify: ok");
179 }
180 }
181}
182
141pub fn set_cursor_visible(v: bool) { 183pub fn set_cursor_visible(v: bool) {
142 sync_scroll(); 184 sync_scroll();
143 unsafe { 185 unsafe {