aboutsummaryrefslogtreecommitdiff
path: root/src/memory/translation_table_descriptors.h
blob: 981c3c78de11567609564b3e748a76fad9515493 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#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