diff options
author | vetch <vetch97@gmail.com> | 2020-01-04 19:37:32 +0100 |
---|---|---|
committer | vetch <vetch97@gmail.com> | 2020-01-04 19:37:32 +0100 |
commit | 615e3302c9dd358bb64cd56d1f3814ad8d5df84d (patch) | |
tree | 07b0469807eb3bff7ff7d3f3576858642bc66675 /src/memory/cp_regs.h | |
parent | 885a097da42317f48cead2d91c0e0240066943a8 (diff) | |
download | rpi-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.h | 114 |
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 |