aboutsummaryrefslogtreecommitdiff
path: root/src/memory/cp_regs.h
diff options
context:
space:
mode:
authorvetch <vetch97@gmail.com>2020-01-04 19:37:32 +0100
committervetch <vetch97@gmail.com>2020-01-04 19:37:32 +0100
commit615e3302c9dd358bb64cd56d1f3814ad8d5df84d (patch)
tree07b0469807eb3bff7ff7d3f3576858642bc66675 /src/memory/cp_regs.h
parent885a097da42317f48cead2d91c0e0240066943a8 (diff)
downloadrpi-MMU-example-615e3302c9dd358bb64cd56d1f3814ad8d5df84d.tar.gz
rpi-MMU-example-615e3302c9dd358bb64cd56d1f3814ad8d5df84d.zip
rearranged files, updated makefile
Diffstat (limited to 'src/memory/cp_regs.h')
-rw-r--r--src/memory/cp_regs.h114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/memory/cp_regs.h b/src/memory/cp_regs.h
new file mode 100644
index 0000000..e5e7063
--- /dev/null
+++ b/src/memory/cp_regs.h
@@ -0,0 +1,114 @@
+#ifndef CP_REGS_H
+#define CP_REGS_H
+
+#include <stdint.h>
+
+// SCTLR - System Control Register
+
+// Wandering why I didn't typedef this struct with fields?
+// That's because
+typedef union
+{
+ uint32_t raw;
+ struct
+ {
+ uint32_t M : 1; // bit 0
+ uint32_t A : 1; // bit 1
+ uint32_t C : 1; // bit 2
+ uint32_t Bits_4_3 : 2; // bits 3:4
+ uint32_t CP15BEN : 1; // bit 5
+ uint32_t Bit_6 : 1; // bit 6
+ uint32_t B : 1; // bit 7
+ uint32_t Bits_9_8 : 2; // bits 9:8
+ uint32_t SW : 1; // bit 10
+ uint32_t Z : 1; // bit 11
+ uint32_t I : 1; // bit 12
+ uint32_t V : 1; // bit 13
+ uint32_t RR : 1; // bit 14
+ uint32_t Bit_15 : 1; // bit 15
+ uint32_t Bit_16 : 1; // bit 16
+ uint32_t HA : 1; // bit 17
+ uint32_t Bit_18 : 1; // bit 18
+ uint32_t WXN : 1; // bit 19
+ uint32_t UWXN : 1; // bit 20
+ uint32_t FI : 1; // bit 21
+ uint32_t U : 1; // bit 22
+ uint32_t Bit_23 : 1; // bit 23
+ uint32_t VE : 1; // bit 24
+ uint32_t EE : 1; // bit 25
+ uint32_t Bit_26 : 1; // bit 26
+ uint32_t NMFI : 1; // bit 27
+ uint32_t TRE : 1; // bit 28
+ uint32_t AFE : 1; // bit 29
+ uint32_t TE : 1; // bit 30
+ uint32_t Bit_31 : 1; // bit 31
+ } fields;
+} SCTLR_t;
+
+// DACR - Domain Access Control Register
+// DACR holds 16 pairs of bits; each pair represents access
+// permissions to a respective memory domain. There's no point
+// declaring a union for this.
+typedef uint32_t DACR_t;
+
+inline static uint8_t domain_permissions(DACR_t DACR_contents,
+ int domain)
+{
+ return (DACR_contents << (30 - 2 * domain)) >> 30;
+}
+
+inline static DACR_t set_domain_permissions(DACR_t DACR_contents,
+ int domain,
+ uint8_t permissions)
+{
+ uint32_t clear_domain_permissions_mask = ~(0b11 << (2 * domain));
+ uint32_t new_domain_permissions_mask =
+ ((uint32_t) permissions) << (2 * domain);
+
+ return (DACR_contents & clear_domain_permissions_mask)
+ | new_domain_permissions_mask;
+}
+
+#define DOMAIN_NO_ACCESS 0b00
+#define DOMAIN_CLIENT_ACCESS 0b01
+#define DOMAIN_RESERVED 0b10
+#define DOMAIN_MANAGER_ACCESS 0b11
+
+// TTBR - Translation Table Base Register (there're 2 of them with
+// (almost) the same structure)
+
+// A field in TTBCR determines how long the address field is in TTBR0,
+// but here we'll ignore this and just assume the greatest possible
+// length of this field (18 bits). In TTBR1 it's always 18 bits.
+typedef union
+{
+ uint32_t raw;
+ struct
+ {
+
+ uint32_t C : 1; // bit 0
+ uint32_t S : 1; // bit 1
+ uint32_t IMP : 1; // bit 2
+ uint32_t RGN : 2; // bits 4:3
+ uint32_t NOS : 1; // bit 5
+ uint32_t IRGN_0 : 1; // bit 6
+ uint32_t Bits_13_6 : 7; // bits 13:7
+ uint32_t Bits_31_14 : 18; // bits 31:14
+ // with multiprocessing extensions the cacheable bit becomes
+ // upper IRGN bit
+#define IRGN_1 C
+
+ // i'm not sure 'interprocess region bits' is the right name,
+ // I'm just guessing (by analogy to RGN -> region bits)
+#define TTBR_CACHEABLE_BIT C
+#define TTBR_INTERPROCESS_REGION_BITS_1 IRGN_1
+#define TTBR_SHAREABLE_BIT S
+#define TTBR_IMPLEMENTATION_DEFINED_BIT IMP
+#define TTBR_REGION_BITS_1_0 RGN
+#define TTBR_INTERPROCESS_REGION_BITS_0 IRGN_0
+#define TTBR_NON_OUTER_SHAREABLE_BIT NOS
+#define TTBR_TRANSLATION_TABLE_BASE_ADDRESS Bits_31_14
+ } fields;
+} TTBR_t;
+
+#endif // CP_REGS_H