forked from M-Labs/zynq-rs
cortex_a9 regs: allow defining bit fields
This commit is contained in:
parent
1e16beb707
commit
69b65b5f72
@ -1,32 +1,63 @@
|
||||
use crate::regs::{RegisterR, RegisterW};
|
||||
use crate::register_bit;
|
||||
use crate::regs::{RegisterR, RegisterW, RegisterRW};
|
||||
|
||||
macro_rules! def_reg_get {
|
||||
macro_rules! def_reg_r {
|
||||
($name:tt, $type: ty, $asm_instr:tt) => {
|
||||
impl RegisterR for $name {
|
||||
type R = $type;
|
||||
|
||||
#[inline(always)]
|
||||
fn read(&self) -> Self::R {
|
||||
let mut value;
|
||||
let mut value: u32;
|
||||
unsafe { asm!($asm_instr : "=r" (value) ::: "volatile") }
|
||||
value
|
||||
value.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! def_reg_set {
|
||||
macro_rules! def_reg_w {
|
||||
($name:ty, $type:ty, $asm_instr:tt) => {
|
||||
impl RegisterW for $name {
|
||||
type W = $type;
|
||||
|
||||
#[inline(always)]
|
||||
fn write(&mut self, value: Self::W) {
|
||||
let value: u32 = value.into();
|
||||
unsafe { asm!($asm_instr :: "r" (value) :: "volatile") }
|
||||
}
|
||||
|
||||
fn zeroed() -> Self::W {
|
||||
0
|
||||
0u32.into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! wrap_reg {
|
||||
($mod_name: ident) => {
|
||||
pub mod $mod_name {
|
||||
pub struct Read {
|
||||
pub inner: u32,
|
||||
}
|
||||
impl From<u32> for Read {
|
||||
fn from(value: u32) -> Self {
|
||||
Read { inner: value }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Write {
|
||||
pub inner: u32,
|
||||
}
|
||||
impl From<u32> for Write {
|
||||
fn from(value: u32) -> Self {
|
||||
Write { inner: value }
|
||||
}
|
||||
}
|
||||
impl Into<u32> for Write {
|
||||
fn into(self) -> u32 {
|
||||
self.inner
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,26 +65,55 @@ macro_rules! def_reg_set {
|
||||
|
||||
/// Stack Pointer
|
||||
pub struct SP;
|
||||
def_reg_get!(SP, u32, "mov $0, sp");
|
||||
def_reg_set!(SP, u32, "mov sp, $0");
|
||||
def_reg_r!(SP, u32, "mov $0, sp");
|
||||
def_reg_w!(SP, u32, "mov sp, $0");
|
||||
|
||||
/// 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");
|
||||
def_reg_r!(LR, u32, "mov $0, lr");
|
||||
def_reg_w!(LR, u32, "mov lr, $0");
|
||||
|
||||
pub struct MPIDR;
|
||||
def_reg_get!(MPIDR, u32, "mrc p15, 0, $0, c0, c0, 5");
|
||||
def_reg_r!(MPIDR, u32, "mrc p15, 0, $0, c0, c0, 5");
|
||||
|
||||
pub struct DFAR;
|
||||
def_reg_get!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0");
|
||||
def_reg_r!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0");
|
||||
|
||||
pub struct DFSR;
|
||||
def_reg_get!(DFSR, u32, "mrc p15, 0, $0, c5, c0, 0");
|
||||
def_reg_r!(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");
|
||||
wrap_reg!(sctlr);
|
||||
def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, $0, c1, c0, 0");
|
||||
def_reg_w!(SCTLR, sctlr::Write, "mcr p15, 0, $0, c1, c0, 0");
|
||||
register_bit!(sctlr,
|
||||
/// Enables MMU
|
||||
m, 0);
|
||||
register_bit!(sctlr,
|
||||
/// Strict Alignment Checking
|
||||
a, 1);
|
||||
register_bit!(sctlr,
|
||||
/// Data Caching
|
||||
c, 2);
|
||||
register_bit!(sctlr, sw, 10);
|
||||
register_bit!(sctlr, z, 11);
|
||||
register_bit!(sctlr, i, 12);
|
||||
register_bit!(sctlr, v, 13);
|
||||
register_bit!(sctlr, ha, 17);
|
||||
register_bit!(sctlr, ee, 25);
|
||||
register_bit!(sctlr,
|
||||
/// (read-only)
|
||||
nmfi, 27);
|
||||
register_bit!(sctlr, unaligned, 22);
|
||||
register_bit!(sctlr,
|
||||
/// TEX Remap Enable
|
||||
tre, 28);
|
||||
register_bit!(sctlr,
|
||||
/// Access Flag Enable
|
||||
afe, 29);
|
||||
register_bit!(sctlr,
|
||||
/// Thumb Exception Enable
|
||||
te, 30);
|
||||
|
||||
/// Invalidate TLBs
|
||||
#[inline(always)]
|
||||
|
@ -68,7 +68,14 @@ fn l1_cache_init() {
|
||||
// (Initialize MMU)
|
||||
|
||||
// Enable I-Cache and D-Cache
|
||||
SCTLR.write(0x00401004);
|
||||
SCTLR.write(
|
||||
SCTLR::zeroed()
|
||||
.m(false)
|
||||
.a(false)
|
||||
.c(true)
|
||||
.i(true)
|
||||
.unaligned(true)
|
||||
);
|
||||
|
||||
// Synchronization barriers
|
||||
// Allows MMU to start
|
||||
|
Loading…
Reference in New Issue
Block a user