#include // 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 CACHEABLE_BIT C #define INTERPROCESS_REGION_BITS_1 IRGN_1 #define SHAREABLE_BIT S #define IMPLEMENTATION_DEFINED_BIT IMP #define REGION_BITS_1_0 RGN #define INTERPROCESS_REGION_BITS_0 IRGN_0 #define NON_OUTER_SHAREABLE_BIT NOS #define TRANSLATION_TABLE_BASE_ADDRESS Bits_31_14 } fields; } TTBR_t;