1use core::fmt::Write;
6use core::{arch::asm, panic::PanicInfo};
7
8use kernel::debug;
9
10use x86_q35::serial::{BlockingSerialPort, COM1_BASE};
11
12fn exit_qemu() -> ! {
17 unsafe {
18 asm!(
19 "
20 mov dx, 0xf4
21 mov al, 0x01
22 out dx,al
23 "
24 );
25 }
26
27 let mut com1 = unsafe { BlockingSerialPort::new(COM1_BASE) };
31 let _ = com1.write_fmt(format_args!(
32 "BUG: QEMU did not exit.\
33 \r\n The isa-debug-exit device is missing or is at a wrong address.\
34 \r\n Please make sure the QEMU command line uses\
35 \r\n the `-device isa-debug-exit,iobase=0xf4,iosize=0x04` argument.\
36 \r\nHINT: Use `killall qemu-system-i386` or the Task Manager to stop.\
37 \r\n"
38 ));
39
40 loop {
43 unsafe { asm!("hlt") }
44 }
45}
46
47#[cfg(not(test))]
49#[panic_handler]
50unsafe fn panic_handler(pi: &PanicInfo) -> ! {
51 let mut com1 = BlockingSerialPort::new(COM1_BASE);
52
53 debug::panic_print(
54 &mut com1,
55 pi,
56 &x86::support::nop,
57 crate::PANIC_RESOURCES.get(),
58 );
59
60 exit_qemu();
61}