blob: c88fa4dd5f876debe3839e78517146343ab74f87 [file] [log] [blame]
Sandrine Bailleux3120ea22017-07-10 13:37:48 +01001/*
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +00002 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
Sandrine Bailleux3120ea22017-07-10 13:37:48 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7/*
8 * This header file contains internal definitions that are not supposed to be
9 * used outside of this library code.
10 */
11
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010012#ifndef XLAT_TABLES_V2_HELPERS_H
13#define XLAT_TABLES_V2_HELPERS_H
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010014
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010015#ifndef XLAT_TABLES_V2_H
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010016#error "Do not include this header file directly. Include xlat_tables_v2.h instead."
17#endif
18
Julius Werner53456fc2019-07-09 13:49:11 -070019#ifndef __ASSEMBLER__
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010020
Antonio Nino Diaz5c97bd12018-08-02 09:57:29 +010021#include <stdbool.h>
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010022#include <stddef.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000023
24#include <platform_def.h>
25
26#include <lib/cassert.h>
27#include <lib/xlat_tables/xlat_tables_arch.h>
28#include <lib/xlat_tables/xlat_tables_defs.h>
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010029
30/* Forward declaration */
31struct mmap_region;
32
Sandrine Bailleux8f23fa82017-09-28 21:58:12 +010033/*
34 * Helper macro to define an mmap_region_t. This macro allows to specify all
35 * the fields of the structure but its parameter list is not guaranteed to
36 * remain stable as we add members to mmap_region_t.
37 */
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010038#define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr) \
Sandrine Bailleux8f23fa82017-09-28 21:58:12 +010039 { \
40 .base_pa = (_pa), \
41 .base_va = (_va), \
42 .size = (_sz), \
43 .attr = (_attr), \
44 .granularity = (_gr), \
45 }
46
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010047/* Struct that holds all information about the translation tables. */
48struct xlat_ctx {
49 /*
50 * Max allowed Virtual and Physical Addresses.
51 */
52 unsigned long long pa_max_address;
53 uintptr_t va_max_address;
54
55 /*
56 * Array of all memory regions stored in order of ascending end address
57 * and ascending size to simplify the code that allows overlapping
58 * regions. The list is terminated by the first entry with size == 0.
59 * The max size of the list is stored in `mmap_num`. `mmap` points to an
60 * array of mmap_num + 1 elements, so that there is space for the final
61 * null entry.
62 */
63 struct mmap_region *mmap;
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010064 int mmap_num;
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010065
66 /*
67 * Array of finer-grain translation tables.
68 * For example, if the initial lookup level is 1 then this array would
69 * contain both level-2 and level-3 entries.
70 */
71 uint64_t (*tables)[XLAT_TABLE_ENTRIES];
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010072 int tables_num;
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +000073#if PLAT_RO_XLAT_TABLES
74 bool readonly_tables;
75#endif
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010076 /*
77 * Keep track of how many regions are mapped in each table. The base
78 * table can't be unmapped so it isn't needed to keep track of it.
79 */
80#if PLAT_XLAT_TABLES_DYNAMIC
81 int *tables_mapped_regions;
82#endif /* PLAT_XLAT_TABLES_DYNAMIC */
83
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +010084 int next_table;
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010085
86 /*
87 * Base translation table. It doesn't need to have the same amount of
88 * entries as the ones used for other levels.
89 */
90 uint64_t *base_table;
91 unsigned int base_table_entries;
92
93 /*
94 * Max Physical and Virtual addresses currently in use by the
95 * translation tables. These might get updated as we map/unmap memory
96 * regions but they will never go beyond pa/va_max_address.
97 */
98 unsigned long long max_pa;
99 uintptr_t max_va;
100
101 /* Level of the base translation table. */
102 unsigned int base_level;
103
Antonio Nino Diaz5c97bd12018-08-02 09:57:29 +0100104 /* Set to true when the translation tables are initialized. */
105 bool initialized;
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100106
107 /*
Antonio Nino Diazf1b84f62018-07-03 11:58:49 +0100108 * Translation regime managed by this xlat_ctx_t. It should be one of
109 * the EL*_REGIME defines.
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100110 */
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100111 int xlat_regime;
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100112};
113
114#if PLAT_XLAT_TABLES_DYNAMIC
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100115#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100116 static int _ctx_name##_mapped_regions[_xlat_tables_count];
117
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100118#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100119 .tables_mapped_regions = _ctx_name##_mapped_regions,
120#else
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100121#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100122 /* do nothing */
123
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100124#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100125 /* do nothing */
126#endif /* PLAT_XLAT_TABLES_DYNAMIC */
127
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000128#if PLAT_RO_XLAT_TABLES
129#define XLAT_CTX_INIT_TABLE_ATTR() \
130 .readonly_tables = false,
131#else
132#define XLAT_CTX_INIT_TABLE_ATTR()
133 /* do nothing */
134#endif
135
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100136#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, \
137 _xlat_tables_count, _virt_addr_space_size, \
138 _phy_addr_space_size, _xlat_regime, _section_name)\
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100139 CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
140 assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
141 \
142 static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
143 \
144 static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
145 [XLAT_TABLE_ENTRIES] \
146 __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
147 \
148 static uint64_t _ctx_name##_base_xlat_table \
149 [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
150 __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
151 * sizeof(uint64_t)); \
152 \
153 XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
154 \
155 static xlat_ctx_t _ctx_name##_xlat_ctx = { \
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100156 .pa_max_address = (_phy_addr_space_size) - 1ULL, \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000157 .va_max_address = (_virt_addr_space_size) - 1UL, \
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100158 .mmap = _ctx_name##_mmap, \
159 .mmap_num = (_mmap_count), \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000160 .tables = _ctx_name##_xlat_tables, \
161 .tables_num = _xlat_tables_count, \
162 XLAT_CTX_INIT_TABLE_ATTR() \
163 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
164 .next_table = 0, \
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100165 .base_table = _ctx_name##_base_xlat_table, \
166 .base_table_entries = \
167 GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000168 .max_pa = 0U, \
169 .max_va = 0U, \
170 .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
171 .initialized = false, \
172 .xlat_regime = (_xlat_regime) \
173 }
174
175#define REGISTER_XLAT_CONTEXT_RO_BASE_TABLE(_ctx_name, _mmap_count, \
176 _xlat_tables_count, _virt_addr_space_size, \
177 _phy_addr_space_size, _xlat_regime, _section_name)\
178 CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
179 assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
180 \
181 static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
182 \
183 static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
184 [XLAT_TABLE_ENTRIES] \
185 __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
186 \
187 static uint64_t _ctx_name##_base_xlat_table \
188 [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
189 __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
190 * sizeof(uint64_t)) \
191 __section(".rodata"); \
192 \
193 XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
194 \
195 static xlat_ctx_t _ctx_name##_xlat_ctx = { \
196 .pa_max_address = (_phy_addr_space_size) - 1ULL, \
197 .va_max_address = (_virt_addr_space_size) - 1UL, \
198 .mmap = _ctx_name##_mmap, \
199 .mmap_num = (_mmap_count), \
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100200 .tables = _ctx_name##_xlat_tables, \
201 .tables_num = _xlat_tables_count, \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000202 XLAT_CTX_INIT_TABLE_ATTR() \
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100203 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name) \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000204 .next_table = 0, \
205 .base_table = _ctx_name##_base_xlat_table, \
206 .base_table_entries = \
207 GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),\
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100208 .max_pa = 0U, \
209 .max_va = 0U, \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000210 .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
Antonio Nino Diaz5c97bd12018-08-02 09:57:29 +0100211 .initialized = false, \
Petre-Ionut Tudore5a6fef2019-11-07 15:18:03 +0000212 .xlat_regime = (_xlat_regime) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100213 }
214
Julius Werner53456fc2019-07-09 13:49:11 -0700215#endif /*__ASSEMBLER__*/
Jeenu Viswambharan58e81482018-04-27 15:06:57 +0100216
Antonio Nino Diaz50eb3742018-07-24 10:20:53 +0100217#endif /* XLAT_TABLES_V2_HELPERS_H */