aboutsummaryrefslogtreecommitdiff
#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