xref: /arm-trusted-firmware/include/lib/xlat_tables/xlat_tables_v2_helpers.h (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2017-2020, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu /*
8*91f16700Schasinglulu  * This header file contains internal definitions that are not supposed to be
9*91f16700Schasinglulu  * used outside of this library code.
10*91f16700Schasinglulu  */
11*91f16700Schasinglulu 
12*91f16700Schasinglulu #ifndef XLAT_TABLES_V2_HELPERS_H
13*91f16700Schasinglulu #define XLAT_TABLES_V2_HELPERS_H
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #ifndef XLAT_TABLES_V2_H
16*91f16700Schasinglulu #error "Do not include this header file directly. Include xlat_tables_v2.h instead."
17*91f16700Schasinglulu #endif
18*91f16700Schasinglulu 
19*91f16700Schasinglulu #ifndef __ASSEMBLER__
20*91f16700Schasinglulu 
21*91f16700Schasinglulu #include <stdbool.h>
22*91f16700Schasinglulu #include <stddef.h>
23*91f16700Schasinglulu 
24*91f16700Schasinglulu #include <platform_def.h>
25*91f16700Schasinglulu 
26*91f16700Schasinglulu #include <lib/cassert.h>
27*91f16700Schasinglulu #include <lib/utils_def.h>
28*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_arch.h>
29*91f16700Schasinglulu #include <lib/xlat_tables/xlat_tables_defs.h>
30*91f16700Schasinglulu 
31*91f16700Schasinglulu /* Forward declaration */
32*91f16700Schasinglulu struct mmap_region;
33*91f16700Schasinglulu 
34*91f16700Schasinglulu /*
35*91f16700Schasinglulu  * Helper macro to define an mmap_region_t.  This macro allows to specify all
36*91f16700Schasinglulu  * the fields of the structure but its parameter list is not guaranteed to
37*91f16700Schasinglulu  * remain stable as we add members to mmap_region_t.
38*91f16700Schasinglulu  */
39*91f16700Schasinglulu #define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)		\
40*91f16700Schasinglulu 	{							\
41*91f16700Schasinglulu 		.base_pa = (_pa),				\
42*91f16700Schasinglulu 		.base_va = (_va),				\
43*91f16700Schasinglulu 		.size = (_sz),					\
44*91f16700Schasinglulu 		.attr = (_attr),				\
45*91f16700Schasinglulu 		.granularity = (_gr),				\
46*91f16700Schasinglulu 	}
47*91f16700Schasinglulu 
48*91f16700Schasinglulu /* Struct that holds all information about the translation tables. */
49*91f16700Schasinglulu struct xlat_ctx {
50*91f16700Schasinglulu 	/*
51*91f16700Schasinglulu 	 * Max allowed Virtual and Physical Addresses.
52*91f16700Schasinglulu 	 */
53*91f16700Schasinglulu 	unsigned long long pa_max_address;
54*91f16700Schasinglulu 	uintptr_t va_max_address;
55*91f16700Schasinglulu 
56*91f16700Schasinglulu 	/*
57*91f16700Schasinglulu 	 * Array of all memory regions stored in order of ascending end address
58*91f16700Schasinglulu 	 * and ascending size to simplify the code that allows overlapping
59*91f16700Schasinglulu 	 * regions. The list is terminated by the first entry with size == 0.
60*91f16700Schasinglulu 	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
61*91f16700Schasinglulu 	 * array of mmap_num + 1 elements, so that there is space for the final
62*91f16700Schasinglulu 	 * null entry.
63*91f16700Schasinglulu 	 */
64*91f16700Schasinglulu 	struct mmap_region *mmap;
65*91f16700Schasinglulu 	int mmap_num;
66*91f16700Schasinglulu 
67*91f16700Schasinglulu 	/*
68*91f16700Schasinglulu 	 * Array of finer-grain translation tables.
69*91f16700Schasinglulu 	 * For example, if the initial lookup level is 1 then this array would
70*91f16700Schasinglulu 	 * contain both level-2 and level-3 entries.
71*91f16700Schasinglulu 	 */
72*91f16700Schasinglulu 	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
73*91f16700Schasinglulu 	int tables_num;
74*91f16700Schasinglulu #if PLAT_RO_XLAT_TABLES
75*91f16700Schasinglulu 	bool readonly_tables;
76*91f16700Schasinglulu #endif
77*91f16700Schasinglulu 	/*
78*91f16700Schasinglulu 	 * Keep track of how many regions are mapped in each table. The base
79*91f16700Schasinglulu 	 * table can't be unmapped so it isn't needed to keep track of it.
80*91f16700Schasinglulu 	 */
81*91f16700Schasinglulu #if PLAT_XLAT_TABLES_DYNAMIC
82*91f16700Schasinglulu 	int *tables_mapped_regions;
83*91f16700Schasinglulu #endif /* PLAT_XLAT_TABLES_DYNAMIC */
84*91f16700Schasinglulu 
85*91f16700Schasinglulu 	int next_table;
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 	/*
88*91f16700Schasinglulu 	 * Base translation table. It doesn't need to have the same amount of
89*91f16700Schasinglulu 	 * entries as the ones used for other levels.
90*91f16700Schasinglulu 	 */
91*91f16700Schasinglulu 	uint64_t *base_table;
92*91f16700Schasinglulu 	unsigned int base_table_entries;
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 	/*
95*91f16700Schasinglulu 	* Max Physical and Virtual addresses currently in use by the
96*91f16700Schasinglulu 	* translation tables. These might get updated as we map/unmap memory
97*91f16700Schasinglulu 	* regions but they will never go beyond pa/va_max_address.
98*91f16700Schasinglulu 	*/
99*91f16700Schasinglulu 	unsigned long long max_pa;
100*91f16700Schasinglulu 	uintptr_t max_va;
101*91f16700Schasinglulu 
102*91f16700Schasinglulu 	/* Level of the base translation table. */
103*91f16700Schasinglulu 	unsigned int base_level;
104*91f16700Schasinglulu 
105*91f16700Schasinglulu 	/* Set to true when the translation tables are initialized. */
106*91f16700Schasinglulu 	bool initialized;
107*91f16700Schasinglulu 
108*91f16700Schasinglulu 	/*
109*91f16700Schasinglulu 	 * Translation regime managed by this xlat_ctx_t. It should be one of
110*91f16700Schasinglulu 	 * the EL*_REGIME defines.
111*91f16700Schasinglulu 	 */
112*91f16700Schasinglulu 	int xlat_regime;
113*91f16700Schasinglulu };
114*91f16700Schasinglulu 
115*91f16700Schasinglulu #if PLAT_XLAT_TABLES_DYNAMIC
116*91f16700Schasinglulu #define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
117*91f16700Schasinglulu 	static int _ctx_name##_mapped_regions[_xlat_tables_count];
118*91f16700Schasinglulu 
119*91f16700Schasinglulu #define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)				\
120*91f16700Schasinglulu 	.tables_mapped_regions = _ctx_name##_mapped_regions,
121*91f16700Schasinglulu #else
122*91f16700Schasinglulu #define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
123*91f16700Schasinglulu 	/* do nothing */
124*91f16700Schasinglulu 
125*91f16700Schasinglulu #define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)				\
126*91f16700Schasinglulu 	/* do nothing */
127*91f16700Schasinglulu #endif /* PLAT_XLAT_TABLES_DYNAMIC */
128*91f16700Schasinglulu 
129*91f16700Schasinglulu #if PLAT_RO_XLAT_TABLES
130*91f16700Schasinglulu #define XLAT_CTX_INIT_TABLE_ATTR()					\
131*91f16700Schasinglulu 	.readonly_tables = false,
132*91f16700Schasinglulu #else
133*91f16700Schasinglulu #define XLAT_CTX_INIT_TABLE_ATTR()
134*91f16700Schasinglulu 	/* do nothing */
135*91f16700Schasinglulu #endif
136*91f16700Schasinglulu 
137*91f16700Schasinglulu #define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,		\
138*91f16700Schasinglulu 			_xlat_tables_count, _virt_addr_space_size,	\
139*91f16700Schasinglulu 			_phy_addr_space_size, _xlat_regime,		\
140*91f16700Schasinglulu 			_table_section, _base_table_section)		\
141*91f16700Schasinglulu 	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),	\
142*91f16700Schasinglulu 		assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
143*91f16700Schasinglulu 									\
144*91f16700Schasinglulu 	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];		\
145*91f16700Schasinglulu 									\
146*91f16700Schasinglulu 	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]	\
147*91f16700Schasinglulu 		[XLAT_TABLE_ENTRIES]					\
148*91f16700Schasinglulu 		__aligned(XLAT_TABLE_SIZE) __section(_table_section);	\
149*91f16700Schasinglulu 									\
150*91f16700Schasinglulu 	static uint64_t _ctx_name##_base_xlat_table			\
151*91f16700Schasinglulu 		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]	\
152*91f16700Schasinglulu 		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
153*91f16700Schasinglulu 			* sizeof(uint64_t))				\
154*91f16700Schasinglulu 		__section(_base_table_section);				\
155*91f16700Schasinglulu 									\
156*91f16700Schasinglulu 	XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
157*91f16700Schasinglulu 									\
158*91f16700Schasinglulu 	static xlat_ctx_t _ctx_name##_xlat_ctx = {			\
159*91f16700Schasinglulu 		.pa_max_address = (_phy_addr_space_size) - 1ULL,	\
160*91f16700Schasinglulu 		.va_max_address = (_virt_addr_space_size) - 1UL,	\
161*91f16700Schasinglulu 		.mmap = _ctx_name##_mmap,				\
162*91f16700Schasinglulu 		.mmap_num = (_mmap_count),				\
163*91f16700Schasinglulu 		.tables = _ctx_name##_xlat_tables,			\
164*91f16700Schasinglulu 		.tables_num = ARRAY_SIZE(_ctx_name##_xlat_tables),	\
165*91f16700Schasinglulu 		 XLAT_CTX_INIT_TABLE_ATTR()				\
166*91f16700Schasinglulu 		 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)			\
167*91f16700Schasinglulu 		.next_table = 0,					\
168*91f16700Schasinglulu 		.base_table = _ctx_name##_base_xlat_table,		\
169*91f16700Schasinglulu 		.base_table_entries =					\
170*91f16700Schasinglulu 			ARRAY_SIZE(_ctx_name##_base_xlat_table),	\
171*91f16700Schasinglulu 		.max_pa = 0U,						\
172*91f16700Schasinglulu 		.max_va = 0U,						\
173*91f16700Schasinglulu 		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
174*91f16700Schasinglulu 		.initialized = false,					\
175*91f16700Schasinglulu 		.xlat_regime = (_xlat_regime)				\
176*91f16700Schasinglulu 	}
177*91f16700Schasinglulu 
178*91f16700Schasinglulu #endif /*__ASSEMBLER__*/
179*91f16700Schasinglulu 
180*91f16700Schasinglulu #endif /* XLAT_TABLES_V2_HELPERS_H */
181