From 69b65b5f7266f9c8371df8f341b6e15f1bb6cdc7 Mon Sep 17 00:00:00 2001 From: Astro Date: Mon, 17 Jun 2019 01:36:11 +0200 Subject: [PATCH] cortex_a9 regs: allow defining bit fields --- src/cortex_a9/regs.rs | 90 +++++++++++++++++++++++++++++++++++-------- src/main.rs | 9 ++++- 2 files changed, 83 insertions(+), 16 deletions(-) diff --git a/src/cortex_a9/regs.rs b/src/cortex_a9/regs.rs index 8cef265..ffe6ac3 100644 --- a/src/cortex_a9/regs.rs +++ b/src/cortex_a9/regs.rs @@ -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 for Read { + fn from(value: u32) -> Self { + Read { inner: value } + } + } + + pub struct Write { + pub inner: u32, + } + impl From for Write { + fn from(value: u32) -> Self { + Write { inner: value } + } + } + impl Into 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)] diff --git a/src/main.rs b/src/main.rs index 5141f40..2ae145e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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