use core::arch::asm;
use core::ffi::{CStr, c_char};
use hyperlight_common::outb::OutBAction;
#[unsafe(no_mangle)]
pub extern "C" fn abort() -> ! {
abort_with_code(&[0, 0xFF])
}
pub fn abort_with_code(code: &[u8]) -> ! {
#[cfg(all(feature = "trace_guest", target_arch = "x86_64"))]
hyperlight_guest_tracing::end_trace();
outb(OutBAction::Abort as u16, code);
outb(OutBAction::Abort as u16, &[0xFF]); unreachable!()
}
pub unsafe fn abort_with_code_and_message(code: &[u8], message_ptr: *const c_char) -> ! {
#[cfg(all(feature = "trace_guest", target_arch = "x86_64"))]
hyperlight_guest_tracing::end_trace();
unsafe {
outb(OutBAction::Abort as u16, code);
let message_bytes = CStr::from_ptr(message_ptr).to_bytes();
outb(OutBAction::Abort as u16, message_bytes);
outb(OutBAction::Abort as u16, &[0xFF]);
unreachable!()
}
}
pub fn write_abort(code: &[u8]) {
outb(OutBAction::Abort as u16, code);
}
pub(crate) fn outb(port: u16, data: &[u8]) {
unsafe {
let mut i = 0;
while i < data.len() {
let remaining = data.len() - i;
let chunk_len = remaining.min(3);
let mut chunk = [0u8; 4];
chunk[0] = chunk_len as u8;
chunk[1..1 + chunk_len].copy_from_slice(&data[i..i + chunk_len]);
let val = u32::from_le_bytes(chunk);
out32(port, val);
i += chunk_len;
}
}
}
pub(crate) unsafe fn out32(port: u16, val: u32) {
#[cfg(all(feature = "trace_guest", target_arch = "x86_64"))]
{
if let Some((ptr, len)) = hyperlight_guest_tracing::serialized_data() {
unsafe {
asm!("out dx, eax",
in("dx") port,
in("eax") val,
in("r8") OutBAction::TraceBatch as u64,
in("r9") ptr,
in("r10") len,
options(preserves_flags, nomem, nostack)
)
};
hyperlight_guest_tracing::reset();
} else {
unsafe {
asm!("out dx, eax", in("dx") port, in("eax") val, options(preserves_flags, nomem, nostack))
};
}
}
#[cfg(not(all(feature = "trace_guest", target_arch = "x86_64")))]
unsafe {
asm!("out dx, eax", in("dx") port, in("eax") val, options(preserves_flags, nomem, nostack));
}
}
pub fn debug_print(msg: &str) {
for byte in msg.bytes() {
unsafe {
out32(OutBAction::DebugPrint as u16, byte as u32);
}
}
}