pub(super) struct AArch64;
impl super::ArchSupport for AArch64 {}
#[macro_export]
macro_rules! read_sysreg {
($name:ident) => {
{
let mut value: u64;
unsafe {
core::arch::asm!(
concat!("mrs {value:x}, ", core::stringify!($name)),
value = out(reg) value,
options(nomem, nostack),
);
}
value
}
}
}
#[macro_export]
macro_rules! write_sysreg {
(reg $dest:ident, imm $imm:literal) => {
{
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($dest), ", {imm}"),
imm = const $imm,
options(nomem, nostack),
)
}
}
};
(reg $dest:ident, imm $imm:literal, $($barrier:literal),+) => {
{
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($dest), ", {imm}"),
$($barrier,)+
imm = const $imm,
options(nomem, nostack),
)
}
}
};
(reg $dest:ident, reg $src:ident) => {
{
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($dest), ", ", core::stringify!($src)),
options(nomem, nostack),
)
}
}
};
(reg $dest:ident, reg $src:ident, $($barrier:literal),+) => {
{
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($dest), ", ", core::stringify!($src)),
$($barrier,)+
options(nomem, nostack),
)
}
}
};
(reg $name:ident, $value:expr) => {
{
let v: u64 = $value;
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($name), ", {value:x}"),
value = in(reg) v,
options(nomem, nostack),
)
}
}
};
(reg $name:ident, $value:expr, $($barrier:literal),+) => {
{
let v: u64 = $value;
unsafe {
core::arch::asm!(
concat!("msr ", core::stringify!($name), ", {value:x}"),
$($barrier,)+
value = in(reg) v,
options(nomem, nostack),
)
}
}
};
}
impl super::Interrupts for AArch64 {
fn enable_interrupts() {
write_sysreg!(reg daifclr, imm 0x02, "isb sy");
}
fn disable_interrupts() {
write_sysreg!(reg daifset, imm 0x02, "isb sy");
}
fn interrupts_enabled() -> bool {
let daif = read_sysreg!(daif);
daif & 0x80 == 0
}
}