#ifndef TRANSLATION_TABLE_DESCRIPTORS_H #define TRANSLATION_TABLE_DESCRIPTORS_H #include <stdint.h> // ARM lets you choose between 32-bit abd 64-bit translation table // descriptors (called short and long descriptors respectively). // The format of the descriptor differs depending on what it describes // (section, supersection, a page table, etc...) and table of which // level of lookup it belongs to. // Even in case of descriptor of a specified type (e.g. short-format // section descriptor), a given field inside it may have different // meanings depending on settings in coprocessor registers... (yeah, ARM // looks a bit messy... all for backward compatibility, i guess) ////// Here are the definitions for short-format descriptors //// short-format page table descriptor typedef struct { uint32_t Bits_1_0 : 1; // bits 1:0 uint32_t PXN : 1; // bit 2 uint32_t NS : 1; // bit 3 uint32_t SBZ : 1; // bit 4 uint32_t Domain_3_0 : 4; // bits 8:5 uint32_t Bit_9 : 1; // bit 9 uint32_t Bits_31_10 : 22; // bits 31:10 #define DESCRIPTOR_TYPE_1_0 Bits_1_0 #define PRIVILEGED_EXECUTE_NEVER_BIT PXN #define NON_SECURE_BIT NS // me thinks SBZ means "should be zero", // but me sees no point #defining it #define DOMAIN_3_0 Domain_3_0 #define IMPLEMENTATION_DEFINED_BIT Bit_9 #define PAGE_TABLE_BASE_ADDRESS_31_10 Bits_31_10 } short_page_table_descriptor_t; //// short-format section descriptor typedef struct { uint32_t PXN : 1; // bit 0 uint32_t Bit_1 : 1; // bit 1 uint32_t B : 1; // bit 2 uint32_t C : 1; // bit 3 uint32_t XN : 1; // bit 4 uint32_t Domain_3_0 : 4; // bits 8:5 uint32_t Bit_9 : 1; // bit 9 uint32_t AP_1_0 : 2; // bit 11:10 uint32_t TEX_2_0 : 3; // bits 14:12 uint32_t AP_2 : 1; // bit 15 uint32_t S : 1; // bit 16 uint32_t nG : 1; // bit 17 uint32_t Bit_18 : 1; // bit 18 uint32_t NS : 1; // bit 19 uint32_t PA_31_20 : 12; // bits 31:20 // some of these are already defined the same for page table //#define PRIVILEGED_EXECUTE_NEVER_BIT PXN #define DESCRIPTOR_TYPE_1 Bit_1 #define BUFFERABLE_BIT B #define CACHEABLE_BIT C #define EXECUTE_NEVER_BIT XN //#define DOMAIN_3_0 Domain_3_0 //#define IMPLEMENTATION_DEFINED_BIT Bit_9 #define ACCESS_PERMISSIONS_1_0 AP_1_0 #define TYPE_EXTENSION_2_0 TEX_2_0 #define ACCESS_PERMISSIONS_2 AP_2 #define SHAREABLE_BIT S #define NON_GLOBAL_BIT nG #define SECTION_OR_SUPERSECTION_BIT Bit_18 //#define NON_SECURE_BIT NS #define SECTION_BASE_ADDRESS_31_20 PA_31_20 } short_section_descriptor_t; //// short-format supersection descriptor typedef struct { uint32_t PXN : 1; // bit 0 uint32_t Bit_1 : 1; // bit 1 uint32_t B : 1; // bit 2 uint32_t C : 1; // bit 3 uint32_t XN : 1; // bit 4 uint32_t PA_39_36 : 4; // bits 8:5 uint32_t Bit_9 : 1; // bit 9 uint32_t AP_1_0 : 2; // bit 11:10 uint32_t TEX_2_0 : 3; // bits 14:12 uint32_t AP_2 : 1; // bit 15 uint32_t S : 1; // bit 16 uint32_t nG : 1; // bit 17 uint32_t Bit_18 : 1; // bit 18 uint32_t NS : 1; // bit 19 uint32_t PA_35_32 : 4; // bits 23:20 uint32_t PA_31_24 : 8; // bits 31:24 // most of these are already defined the same for section //#define PRIVILEGED_EXECUTE_NEVER_BIT PXN //#define DESCRIPTOR_TYPE_1 Bit_1 //#define BUFFERABLE_BIT B //#define CACHEABLE_BIT C //#define EXECUTE_NEVER_BIT XN #define SUPERSECTION_BASE_ADDRESS_39_36 PA_39_36 //#define IMPLEMENTATION_DEFINED_BIT Bit_9 //#define ACCESS_PERMISSIONS_1_0 AP_1_0 //#define TYPE_EXTENSION_2_0 TEX_2_0 //#define ACCESS_PERMISSIONS_2 AP_2 //#define SHAREABLE_BIT S //#define NON_GLOBAL_BIT nG //#define SECTION_OR_SUPERSECTION_BIT Bit_18 //#define NON_SECURE_BIT NS #define SUPERSECTION_BASE_ADDRESS_35_32 PA_35_32 #define SUPERSECTION_BASE_ADDRESS_31_24 PA_31_24 } short_supersection_descriptor_t; //// possible access permission field values // How AP[2:0] is used depends on settings in SCTLR.AFE // Meaning of #define'd names below: // RW - read-write // RO - read-only // PL1 - a given permission applies to privilege level PL1 // PL2 - a given permission applies to privilege level PL2 // ALL - a given permission applies to both privilege levels // If only a permission for one privilege level is given in the name, // it means the other one has no access. // When SCTLR.AFE is 0 (access flag not used) and short-format // descritor table is used, the following access permission control // schema for AP[2:0] is used: #define AP_2_0_MODEL_NO_ACCESS 0b000 #define AP_2_0_MODEL_RW_PL1 0b001 #define AP_2_0_MODEL_RW_PL1_RO_PL0 0b010 #define AP_2_0_MODEL_RW_ALL 0b011 #define AP_2_0_MODEL_RESERVED 0b100 #define AP_2_0_MODEL_RO_PL1 0b101 #define AP_2_0_MODEL_RO_ALL_DEPRECATED 0b110 // use 0b111 instead #define AP_2_0_MODEL_RO_ALL 0b111 // reserved in VMSAv6 // TODO: the #define's of RO_ALL and reserved could be done // conditionally depending on the VMSA version available (either give // the programmer #including this the possibility to #define their // VMSA version or assume the VMSA version respective to the ARM // version we're compiling against) //// Values for bit18, that determines whether a descriptor describes // section or supersection: #define DESCRIBES_SECTION 0b0 #define DESCRIBES_SUPERSECTION 0b1 //// short-format descriptor generic type typedef union { uint32_t raw; uint8_t descriptor_type : 2; short_page_table_descriptor_t page_table_fields; short_section_descriptor_t section_fields; short_supersection_descriptor_t supersection_fields; } short_descriptor_lvl1_t; //// possible values of descriptor_type field: #define SHORT_DESCRIPTOR_INVALID 0b00 #define SHORT_DESCRIPTOR_PAGE_TABLE 0b01 #define SHORT_DESCRIPTOR_SECTION_OR_SUPERSECTION 0b10 #define SHORT_DESCRIPTOR_SECTION_OR_SUPERSECTION_PXN 0b11 // on an implementation that does not support the PXN attribute // 0b11 should not be used #define SHORT_DESCRIPTOR_RESERVED 0b11 #endif // TRANSLATION_TABLE_DESCRIPTORS_H