2019-06-12 06:20:23 +08:00
|
|
|
use crate::regs::{RegisterR, RegisterW};
|
2019-05-05 20:56:23 +08:00
|
|
|
|
|
|
|
macro_rules! def_reg_get {
|
2019-06-12 06:20:23 +08:00
|
|
|
($name:tt, $type: ty, $asm_instr:tt) => {
|
|
|
|
impl RegisterR for $name {
|
|
|
|
type R = $type;
|
|
|
|
|
2019-05-05 20:56:23 +08:00
|
|
|
#[inline(always)]
|
2019-06-12 06:20:23 +08:00
|
|
|
fn read(&self) -> Self::R {
|
2019-05-05 20:56:23 +08:00
|
|
|
let mut value;
|
|
|
|
unsafe { asm!($asm_instr : "=r" (value) ::: "volatile") }
|
|
|
|
value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! def_reg_set {
|
|
|
|
($name:ty, $type:ty, $asm_instr:tt) => {
|
2019-06-12 06:20:23 +08:00
|
|
|
impl RegisterW for $name {
|
|
|
|
type W = $type;
|
|
|
|
|
2019-05-05 20:56:23 +08:00
|
|
|
#[inline(always)]
|
2019-06-12 06:20:23 +08:00
|
|
|
fn write(&mut self, value: Self::W) {
|
2019-05-05 20:56:23 +08:00
|
|
|
unsafe { asm!($asm_instr :: "r" (value) :: "volatile") }
|
|
|
|
}
|
2019-06-12 06:20:23 +08:00
|
|
|
|
|
|
|
fn zeroed() -> Self::W {
|
|
|
|
0
|
|
|
|
}
|
2019-05-05 20:56:23 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-27 07:44:24 +08:00
|
|
|
/// Stack Pointer
|
2019-05-05 20:56:23 +08:00
|
|
|
pub struct SP;
|
|
|
|
def_reg_get!(SP, u32, "mov $0, sp");
|
|
|
|
def_reg_set!(SP, u32, "mov sp, $0");
|
|
|
|
|
2019-05-27 07:44:24 +08:00
|
|
|
/// Link register (function call return address)
|
|
|
|
pub struct LR;
|
|
|
|
def_reg_get!(LR, u32, "mov $0, lr");
|
|
|
|
def_reg_set!(LR, u32, "mov lr, $0");
|
|
|
|
|
2019-05-05 20:56:23 +08:00
|
|
|
pub struct MPIDR;
|
|
|
|
def_reg_get!(MPIDR, u32, "mrc p15, 0, $0, c0, c0, 5");
|
2019-05-24 01:05:06 +08:00
|
|
|
|
2019-06-12 06:20:23 +08:00
|
|
|
pub struct DFAR;
|
|
|
|
def_reg_get!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0");
|
|
|
|
|
|
|
|
pub struct DFSR;
|
|
|
|
def_reg_get!(DFSR, u32, "mrc p15, 0, $0, c5, c0, 0");
|
|
|
|
|
|
|
|
pub struct SCTLR;
|
|
|
|
def_reg_get!(SCTLR, u32, "mrc p15, 0, $0, c1, c0, 0");
|
|
|
|
def_reg_set!(SCTLR, u32, "mcr p15, 0, $0, c1, c0, 0");
|
|
|
|
|
2019-05-24 01:05:06 +08:00
|
|
|
/// Invalidate TLBs
|
2019-06-12 06:20:23 +08:00
|
|
|
#[inline(always)]
|
2019-05-24 01:05:06 +08:00
|
|
|
pub fn tlbiall() {
|
|
|
|
unsafe {
|
|
|
|
asm!("mcr p15, 0, $0, c8, c7, 0" :: "r" (0) :: "volatile");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Invalidate I-Cache
|
2019-06-12 06:20:23 +08:00
|
|
|
#[inline(always)]
|
2019-05-24 01:05:06 +08:00
|
|
|
pub fn iciallu() {
|
|
|
|
unsafe {
|
|
|
|
asm!("mcr p15, 0, $0, c7, c5, 0" :: "r" (0) :: "volatile");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Invalidate Branch Predictor Array
|
2019-06-12 06:20:23 +08:00
|
|
|
#[inline(always)]
|
2019-05-24 01:05:06 +08:00
|
|
|
pub fn bpiall() {
|
|
|
|
unsafe {
|
|
|
|
asm!("mcr p15, 0, $0, c7, c5, 6" :: "r" (0) :: "volatile");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Invalidate D-Cache
|
2019-06-12 06:20:23 +08:00
|
|
|
#[inline(always)]
|
2019-05-24 01:05:06 +08:00
|
|
|
pub fn dccisw() {
|
|
|
|
// TODO: $0 is r11 at what value?
|
|
|
|
unsafe {
|
|
|
|
asm!("mcr p15, 0, $0, c7, c5, 6" :: "r" (0) :: "volatile");
|
|
|
|
}
|
|
|
|
}
|