From 4b139cfc2fca63d1b3dd760cef9bd6349e55ec72 Mon Sep 17 00:00:00 2001 From: Brad Bondurant Date: Thu, 10 Nov 2022 09:22:06 -0500 Subject: [PATCH] libcortex_r5: add register definitions --- libcortex_r5/src/regs.rs | 374 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 374 insertions(+) create mode 100644 libcortex_r5/src/regs.rs diff --git a/libcortex_r5/src/regs.rs b/libcortex_r5/src/regs.rs new file mode 100644 index 0000000..24bf00b --- /dev/null +++ b/libcortex_r5/src/regs.rs @@ -0,0 +1,374 @@ +use libregister::{ + register_bit, register_bits, + RegisterR, RegisterW, RegisterRW, +}; +use libcortex_a9::{def_reg_r, def_reg_w, wrap_reg}; +pub use libcortex_a9::regs::{SP, LR}; + + +/// Multiprocessor Affinity Register +pub struct MPIDR; +wrap_reg!(mpidr); +def_reg_r!(MPIDR, mpidr::Read, "mrc p15, 0, $0, c0, c0, 5"); +// CPU ID +register_bits!(mpidr, cpu_id, u8, 0, 7); +// group ID +register_bits!(mpidr, group_id, u8, 8, 15); +// 0b11 if part of uniprocessor system +register_bits!(mpidr, u, u8, 30, 31); + +/// System Control Register +pub struct SCTLR; +wrap_reg!(sctlr); +def_reg_r!(SCTLR, sctlr::Read, "mrc p15, 0, $0, c1, c0, 0"); +def_reg_w!(SCTLR, sctlr::Write, "mrc p15, 0, $0, c1, c0, 0"); +// MPU enable +register_bit!(sctlr, m, 0); +// strict alignment +register_bit!(sctlr, a, 1); +// L1 data cache enable +register_bit!(sctlr, c, 2); +// enable SWP and SWPB instructions +register_bit!(sctlr, sw, 10); +// enable branch prediction (SBO) +register_bit!(sctlr, z, 11); +// L1 instruction cache enable +register_bit!(sctlr, i, 12); +// Determines the location of exception vectors: +// 0 = normal exception vectors selected, address range = 0x00000000-0x0000001C +// 1 = high exception vectors (HIVECS) selected, address range = 0xFFFF0000-0xFFFF001C. +// The primary input VINITHIm defines the reset value. +register_bit!(sctlr, v, 13); +// Round-robin bit, controls replacement strategy for instruction and data caches: +// 0 = random replacement strategy +// 1 = round-robin replacement strategy. +// The reset value of this bit is 0. The processor always uses a random replacement strategy, regardless of the state +// of this bit. +register_bit!(sctlr, rr, 14); +// MPU background region enable +register_bit!(sctlr, br, 17); +// Divide by zero: +// 0 = do not generate an Undefined Instruction exception +// 1 = generate an Undefined Instruction exception. +// The reset value of this bit is 0 +register_bit!(sctlr, dz, 19); +// Fast Interrupts enable. +// On the processor Fast Interrupts are always enabled. This bit is SBO +register_bit!(sctlr, fi, 21); +// Configures vectored interrupt: +// 0 = exception vector address for IRQ is 0x00000018 or 0xFFFF0018. See V bit. +// 1 = VIC controller provides handler address for IRQ. +// The reset value of this bit is 0. +register_bit!(sctlr, ve, 24); +// Determines how the E bit in the CPSR is set on an exception: +// 0 = CPSR E bit is set to 0 on an exception +// 1 = CPSR E bit is set to 1 on an exception. +// The primary input CFGEE defines the reset value. +register_bit!(sctlr, ee, 25); +// NMFI, non-maskable fast interrupt enable: +// 0 = Software can disable FIQs +// 1 = Software cannot disable FIQs. +// This bit is read-only. The configuration input CFGNMFIm defines its value. +register_bit!(sctlr, nmfi, 27); +// TEX Remap Enable. On the processor this bit is SBZ. +register_bit!(sctlr, tre, 28); +// Access Flag Enable. On the processor this bit is SBZ. +register_bit!(sctlr, afe, 29); +// Thumb exception enable: +// 0 = enable ARM exception generation +// 1 = enable Thumb exception generation. +// The primary input TEINIT defines the reset value +register_bit!(sctlr, te, 30); +// Identifies little or big instruction endianness in use: +// 0 = little-endianness +// 1 = big-endianness. +// The primary input CFGIE defines the value. This bit is read-only +register_bit!(sctlr, ie, 31); + +/// Auxiliary Control Register +pub struct ACTLR; +wrap_reg!(actlr); +def_reg_r!(ACTLR, actlr::Read, "mrc p15, 0, $0, c1, c0, 1"); +def_reg_w!(ACTLR, actlr::Write, "mcr p15, 0, $0, c1, c0, 1"); +// A(B0/1)TCM external error enable: +// 0 = Disabled +// 1 = Enabled. +// The primary input ERRENRAMm[0] defines the reset value. +register_bit!(actlr, atcmecen, 0); +register_bit!(actlr, b0tcmecen, 1); +register_bit!(actlr, b1tcmecen, 2); +// Cache error control for cache parity and ECC errors +register_bits!(actlr, cec, u8, 3, 5); +// Disable low interrupt latency on all load/store instructions +register_bit!(actlr, dils, 6); +// sMOV of a divide does not complete out of order. +// No other instruction is issued until the divide is finished +register_bit!(actlr, smov, 7); +// Force D-side to not-shared when MPU is off: +// 0 = Normal operation. This is the reset value. +// 1 = D-side normal Non-cacheable forced to Non-shared when MPU is off. +register_bit!(actlr, fdsns, 8); +// Force write-through (WT) for write-back (WB) regions: +// 0 = No forcing of WT. This is the reset value. +// 1 = WT forced for WB regions +register_bit!(actlr, fwt, 9); +// Force outer read allocate (ORA) for outer write allocate (OWA) regions: +// 0 = No forcing of ORA. This is the reset value. +// 1 = ORA forced for OWA regions +register_bit!(actlr, fora, 10); +// Disable data forwarding for Non-cacheable accesses in the AXI master: +// 0 = Normal operation. This is the reset value. +// 1 = Disable data forwarding for Non-cacheable accesses +register_bit!(actlr, dnch, 11); +// Enable random parity error generation: +// 0 = Random parity error generation disabled. This is the reset value. +// 1 = Enable random parity error generation in the cache RAMs. +register_bit!(actlr, erpeg, 12); +// Disable linefill optimization in the AXI master: +// 0 = Normal operation. This is the reset value. +// 1 = Limits the number of outstanding data linefills to two +register_bit!(actlr, dlfo, 13); +// Disable write burst in the AXI master: +// 0 = Normal operation. This is the reset value. +// 1 = Disable write burst optimization +register_bit!(actlr, dbwr, 14); +// This field controls the branch prediction policy: +// b00 = Normal operation. This is the reset value. +// b01 = Branch always taken and history table updates disabled. +// b10 = Branch always not taken and history table updates disabled. +// b11 = Reserved. Behavior is Unpredictable if this field is set to b11 +register_bits!(actlr, bp, u8, 15, 16); +// Return stack disable: +// 0 = Normal return stack operation. This is the reset value. +// 1 = Return stack disabled. +register_bit!(actlr, rsdis, 17); +// Fetch rate control disable: +// 0 = Normal fetch rate control operation. This is the reset value. +// 1 = Fetch rate control disabled. +register_bit!(actlr, frcdis, 19); +// Disable Branch History (BH) extension: +// 0 = Enable the extension. This is the reset value. +// 1 = Disable the extension +register_bit!(actlr, dbhe, 20); +// Disable end of loop prediction: +// 0 = Enable loop prediction. This is the reset value. +// 1 = Disable loop prediction. +register_bit!(actlr, deolp, 21); +// Disable Low Interrupt Latency (LIL) on load/store multiples: +// 0 = Enable LIL on load/store multiples. This is the reset value. +// 1 = Disable LIL on all load/store multiples. +register_bit!(actlr, dilsm, 22); +// AXI slave cache RAM non-privileged access enable: +// 0 = Disabled. This is the reset value. +// 1 = Enabled +register_bit!(actlr, axiscuen, 23); +// AXI slave cache RAM access enable: +// 0 = Disabled. This is the reset value. +// 1 = Enabled +register_bit!(actlr, axiscen, 24); +// A(B0/1)TCM ECC check enable: +// 0 = Disabled +// 1 = Enabled +// The primary input PARECCENRAMm[0] defines the reset value +register_bit!(actlr, atcmpcen, 25); +register_bit!(actlr, b0tcmpcen, 26); +register_bit!(actlr, b1tcmpcen, 27); +// Case A(B1, B2, C) dual issue control: +// 0 = Enabled. This is the reset value. +// 1 = Disabled. +register_bit!(actlr, diadi, 28); +register_bit!(actlr, dib1di, 29); +register_bit!(actlr, dib2di, 30); +register_bit!(actlr, dicdi, 31); + +/// Secondary Auxiliary Control Register +pub struct SACTLR; +wrap_reg!(sactlr); +def_reg_r!(SACTLR, sactlr::Read, "mrc p15, 0, $0, c15, c0, 0"); +def_reg_w!(SACTLR, sactlr::Write, "mcr p15, 0, $0, c15, c0, 0"); +// Enables 64-bit stores for the ATCM. When enabled, the processor uses read-modify-write to ensure that all +// reads and writes presented on the ATCM port are 64 bits wide. +// 0 = Disabled +// 1 = Enabled. +// The primary input RMWENRAMm[0] defines the reset value. +register_bit!(sactlr, atcmrmw, 0); +register_bit!(sactlr, btcmrmw, 1); +// Correction for internal ECC logic on ATCM port. +// 0 = Enabled. This is the reset value. +// 1 = Disabled +register_bit!(sactlr, atcmecc, 2); +register_bit!(sactlr, btcmecc, 3); +// Floating-point input denormal exception output mask. +// 0 = Mask floating-point input denormal exception output. The output FPIDCm is forced to zero. This is +// the reset value. +// 1 = Propagate floating-point input denormal exception flag FPSCR.IDC to output FPIDCm +register_bit!(sactlr, idc, 8); +// Floating-point divide-by-zero exception output mask. +// 0 = Mask floating-point divide-by-zero exception output. The output FPDZCm is forced to zero. This is +// the reset value. +// 1 = Propagate floating-point divide-by-zero exception flag FPSCR.DZC to output FPDZCm +register_bit!(sactlr, dzc, 9); +// Floating-point invalid operation exception output mask. +// 0 = Mask floating-point invalid operation exception output. The output FPIOCm is forced to zero. This is +// the reset value. +// 1 = Propagate floating-point invalid operation exception flag FPSCR.IOC to output FPIOCm. +register_bit!(sactlr, ioc, 10); +// Floating-point underflow exception output mask. +// 0 = Mask floating-point underflow exception output. The output FPUFCm is forced to zero. This is the +// reset value. +// 1 = Propagate floating-point underflow exception flag FPSCR.UFC to output FPUFCm +register_bit!(sactlr, ufc, 11); +// Floating-point overflow exception output mask. +// 0 = Mask floating-point overflow exception output. The output FPOFCm is forced to zero. This is the reset +// value. +// 1 = Propagate floating-point overflow exception flag FPSCR.OFC to output FPOFCm +register_bit!(sactlr, ofc, 12); +// Floating-point inexact exception output mask. +// 0 = Mask floating-point inexact exception output. The output FPIXCm is forced to zero. This is the reset +// value. +// 1 = Propagate floating point inexact exception flag FPSCR.IXC to output FPIXCm +register_bit!(sactlr, ixc, 13); +// Out-of-order FMACS control. +// 0 = Enabled. This is the reset value. +// 1 = Disabled +register_bit!(sactlr, doofmacs, 16); +// Out-of-order double-precision floating point instruction control. +// 0 = Enabled. This is the reset value. +// 1 = Disabled. +register_bit!(sactlr, doodpfp, 17); +// F1/F3/F4dual issue control. +// 0 = Enabled. This is the reset value. +// 1 = Disabled. +register_bit!(sactlr, ddi, 18); +// F2_Id/F2_st/F2D dual issue control. +// 0 = Enabled. This is the reset value. +// 1 = Disabled +register_bit!(sactlr, df2di, 19); +// F6 dual issue control. +// 0 = Enabled. This is the reset value. +// 1 = Disabled +register_bit!(sactlr, df6di, 20); +// Enable random 2-bit error generation in cache RAMs. This bit has no effect unless ECC is configured, see +// Configurable options on page 1-6. +// 0 = Disabled. This is the reset value. +// 1 = Enabled. +register_bit!(sactlr, dr2b, 21); +// Disable hard-error support in the caches. +// 0 = Enabled. The cache logic recovers from some hard errors. +// 1 = Disabled. Most hard errors in the caches are fatal. This is the reset value +register_bit!(sactlr, dche, 22); + +/// Data Fault Status Register +pub struct DFSR; +wrap_reg!(dfsr); +def_reg_r!(DFSR, dfsr::Read, "mrc p15, 0, $0, c5, c0, 0"); +// Indicates the type of fault generated. To determine the data fault, you must use bit [12] and bit [10] in +// conjunction with bits [3:0]. +register_bits!(dfsr, status, u8, 0, 3); +register_bit!(dfsr, s, 10); +// Indicates whether a read or write access caused an abort: +// 0 = read access caused the abort +// 1 = write access caused the abort. +register_bit!(dfsr, rw, 11); +// Distinguishes between an AXI Decode or Slave error on an external abort. This bit is only valid for external +// aborts. For all other aborts types of abort, this bit is set to zero: +// 0 = AXI Decode error (DECERR), or AHB error, caused the abort +// 1 = AXI Slave error (SLVERR), or unsupported exclusive access, for example exclusive access using the AHB +// peripheral port, caused the abort. +register_bit!(dfsr, sd, 12); + +/// Data Fault Address Register +pub struct DFAR; +def_reg_r!(DFAR, u32, "mrc p15, 0, $0, c6, c0, 0"); + +/// MPU Type Register +pub struct MPUIR; +wrap_reg!(mpuir); +def_reg_r!(MPUIR, mpuir::Read, "mrc p15, 0, $0, c0, c0, 4"); +// number of unified MPU regions (0, 12, or 16) +register_bits!(mpuir, d_region, u8, 8, 15); + +/// MPU Region Number Register +pub struct RGNR; +wrap_reg!(rgnr); +def_reg_r!(RGNR, rgnr::Read, "mrc p15, 0, $0, c6, c2, 0"); +def_reg_w!(RGNR, rgnr::Write, "mcr p15, 0, $0, c6, c2, 0"); +register_bits!(rgnr, region, u8, 0, 3); + +/// MPU Region Access Control Registers +pub struct RACTLR; +wrap_reg!(ractlr); +def_reg_r!(RACTLR, ractlr::Read, "mrc p15, 0, $0, c6, c1, 4"); +def_reg_w!(RACTLR, ractlr::Write, "mcr p15, 0, $0, c6, c1, 4"); +// bufferable +register_bit!(ractlr, b, 0); +// cacheable +register_bit!(ractlr, c, 1); +// shareable +register_bit!(ractlr, s, 2); +// type extension +register_bits!(ractlr, tex, u8, 3, 5); +// Access permission +register_bits!(ractlr, ap, u8, 8, 10); +// Execute Never. Determines if a region of memory is executable: +// 0 = all instruction fetches enabled +// 1 = no instruction fetches enabled. +register_bit!(ractlr, xn, 12); + +/// MPU Region Size and Enable Registers +pub struct RSER; +wrap_reg!(rser); +def_reg_r!(RSER, rser::Read, "mrc p15, 0, $0, c6, c1, 2"); +def_reg_w!(RSER, rser::Write, "mcr p15, 0, $0, c6, c1, 2"); +// enable region +register_bit!(rser, enable, 0); +// Defines the region size: +// b00000 - b00011=Unpredictable +// b00100 = 32 bytes +// b00101 = 64 bytes +// b00110 = 128 bytes +// b00111 = 256 bytes +// b01000 = 512 bytes +// b01001 = 1KB +// b01010 = 2KB +// b01011 = 4KB +// b01100 = 8KB +// b01101 = 16KB +// b01110 = 32KB +// b01111 = 64KB +// b10000 = 128KB +// b10001 = 256KB +// b10010 = 512KB +// b10011 = 1MB +// b10100 = 2MB +// b10101 = 4MB +// b10110 = 8MB +// b10111 = 16MB +// b11000 = 32MB +// b11001 = 64MB +// b11010 = 128MB +// b11011 = 256MB +// b11100 = 512MB +// b11101 = 1GB +// b11110 = 2GB +// b11111 = 4GB +register_bits!(rser, region_size, u8, 1, 5); +// Each bit position represents a sub-region, 0-7. +// Bit [8] corresponds to sub-region 0 +// ... +// Bit [15] corresponds to sub-region 7 +// The meaning of each bit is: +// 0 = address range is part of this region +// 1 = address range is not part of this region +register_bits!(rser, subregion_disable, u8, 8, 15); + +/// MPU Region Base Address Registers +pub struct RBAR; +wrap_reg!(rbar); +def_reg_r!(RBAR, rbar::Read, "mrc p15, 0, $0, c6, c1, 0"); +def_reg_w!(RBAR, rbar::Write, "mcr p15, 0, $0, c6, c1, 0"); +// base address +register_bits!(rbar, base_address, u32, 5, 31); + + +// TODO: TCM registers (R5 TRM sec 4.3.23-25)