summaryrefslogtreecommitdiffstats
path: root/rsdos/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--rsdos/src/main.rs62
1 files changed, 59 insertions, 3 deletions
diff --git a/rsdos/src/main.rs b/rsdos/src/main.rs
index 27dab06..0e159e6 100644
--- a/rsdos/src/main.rs
+++ b/rsdos/src/main.rs
@@ -247,6 +247,25 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut
247 } 247 }
248 rsnix::interrupts::init(); 248 rsnix::interrupts::init();
249 rsnix::serial_println!("intr: IDT loaded, PIC remapped, timer ~100 Hz"); 249 rsnix::serial_println!("intr: IDT loaded, PIC remapped, timer ~100 Hz");
250 // Prove the timer actually ticks before handing the machine to the
251 // scheduler: if the PIC/APIC route is broken on real hardware, the
252 // first `hlt` (shell input, idle) never wakes and the system silently
253 // freezes. Spin briefly with interrupts on and require uptime to
254 // advance; a dead timer becomes a visible panic instead.
255 let t0 = rsnix::interrupts::uptime_ms();
256 let mut timer_ok = false;
257 for _ in 0..2_000_000 {
258 core::hint::spin_loop();
259 if rsnix::interrupts::uptime_ms() != t0 {
260 timer_ok = true;
261 break;
262 }
263 }
264 if timer_ok {
265 rsnix::serial_println!("intr: timer verified (uptime advances)");
266 } else {
267 panic!("timer: no PIT tick within 2M spins — interrupt routing broken");
268 }
250 rsnix::gop::boot_marker("rsnix: serial+ps2+gdt+intr ok"); 269 rsnix::gop::boot_marker("rsnix: serial+ps2+gdt+intr ok");
251 270
252 dump_memory_summary(); 271 dump_memory_summary();
@@ -347,13 +366,50 @@ pub unsafe extern "efiapi" fn efi_main(image_handle: Handle, system_table: *mut
347 366
348 rsnix::serial_println!("boot: entering shell"); 367 rsnix::serial_println!("boot: entering shell");
349 rsnix::gop::boot_marker("rsnix: boot done — shell"); 368 rsnix::gop::boot_marker("rsnix: boot done — shell");
350 // USB (xHCI) mouse is polled; fall back to PS/2 if no USB mouse. 369 // USB (xHCI) / EHCI mouse is polled; fall back to PS/2 if no USB mouse.
351 rsnix::usb::init(); 370 // Each stage draws its own marker: a real-hardware freeze leaves the
352 if rsnix::ps2::mouse_present() || rsnix::usb::controller_up() { 371 // last completed stage on the screen, so the hang point is identifiable
372 // without a serial console.
373 // STOPGAP: skip ALL USB host-controller init so the BIOS USB-Legacy SMI
374 // keeps emulating the keyboard/mouse on the 8042 (PS/2). Resetting the
375 // EHCI without a completed USBLEGSUP ownership handshake killed the
376 // firmware's legacy emulation, leaving the OptiPlex 7010 with zero input.
377 // While NO_USB is set, USB input is served entirely by the BIOS (IRQ1/
378 // IRQ12 + our PS/2 driver) and no EHCI/xHCI/UHCI register is touched.
379 const NO_USB: bool = false;
380 rsnix::gop::boot_marker("rsnix: usb init");
381 if !NO_USB {
382 rsnix::usb::init();
383 } else {
384 rsnix::serial_println!("usb: init skipped (stopgap) — BIOS USB-Legacy owns input");
385 }
386 rsnix::gop::boot_marker("rsnix: ehci init");
387 if !NO_USB {
388 rsnix::ehci::init();
389 } else {
390 rsnix::serial_println!("ehci: init skipped (stopgap)");
391 }
392 rsnix::gop::boot_marker("rsnix: uhci init");
393 if !NO_USB {
394 rsnix::uhci::init();
395 } else {
396 rsnix::serial_println!("uhci: init skipped (stopgap)");
397 }
398 if rsnix::ps2::mouse_present()
399 || rsnix::usb::controller_up()
400 || rsnix::ehci::controller_up()
401 || rsnix::uhci::controller_up()
402 {
403 rsnix::gop::boot_marker("rsnix: cursor spawn");
353 rsnix::cursor::spawn(); 404 rsnix::cursor::spawn();
354 } else { 405 } else {
355 rsnix::serial_println!("cursor: no mouse — overlay disabled"); 406 rsnix::serial_println!("cursor: no mouse — overlay disabled");
356 } 407 }
408 rsnix::gop::boot_marker("rsnix: shell run");
409 // The shell REPL is about to start: from here on task 0 may legitimately
410 // park in poll_key with a fixed frame, so the watchdog's boot-phase spin
411 // rule for task 0 is disarmed (boot-phase hangs already panicked).
412 rsnix::sched::mark_shell_running();
357 // Shell-entry self-check: verify the vt grid structs are sane right 413 // Shell-entry self-check: verify the vt grid structs are sane right
358 // before the shell's first print. The OptiPlex crashes in the first 414 // before the shell's first print. The OptiPlex crashes in the first
359 // banner write when the cells VecData (or the shadow) holds the 415 // banner write when the cells VecData (or the shadow) holds the