use crate::QEMUExit;
use core::arch::asm;
const EXIT_SUCCESS: u32 = 0;
const EXIT_FAILURE: u32 = 1;
#[allow(non_upper_case_globals)]
const ADP_Stopped_ApplicationExit: u64 = 0x20026;
#[repr(C)]
struct QEMUParameterBlock {
arg0: u64,
arg1: u64,
}
pub struct AArch64 {}
fn semihosting_sys_exit_call(block: &QEMUParameterBlock) -> ! {
unsafe {
asm!(
"hlt #0xF000",
in("x0") 0x18,
in("x1") block as *const _ as u64,
options(nostack)
);
loop {
asm!("wfe", options(nomem, nostack));
}
}
}
impl AArch64 {
pub const fn new() -> Self {
AArch64 {}
}
}
impl QEMUExit for AArch64 {
fn exit(&self, code: u32) -> ! {
let block = QEMUParameterBlock {
arg0: ADP_Stopped_ApplicationExit,
arg1: code as u64,
};
semihosting_sys_exit_call(&block)
}
fn exit_success(&self) -> ! {
self.exit(EXIT_SUCCESS)
}
fn exit_failure(&self) -> ! {
self.exit(EXIT_FAILURE)
}
}