xref: /rk3399_ARM-atf/include/lib/xlat_tables/xlat_tables_v2_helpers.h (revision d48f193d11b4d4dca2675646ad76147f2d4765f2)
1 /*
2  * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3  *
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 
12 #ifndef __XLAT_TABLES_V2_HELPERS_H__
13 #define __XLAT_TABLES_V2_HELPERS_H__
14 
15 #ifndef __XLAT_TABLES_V2_H__
16 #error "Do not include this header file directly. Include xlat_tables_v2.h instead."
17 #endif
18 
19 /* Offsets into mmu_cfg_params array. All parameters are 32 bits wide. */
20 #define MMU_CFG_MAIR0		0
21 #define MMU_CFG_TCR		1
22 #define MMU_CFG_TTBR0_LO	2
23 #define MMU_CFG_TTBR0_HI	3
24 #define MMU_CFG_PARAM_MAX	4
25 
26 #ifndef __ASSEMBLY__
27 
28 #include <cassert.h>
29 #include <platform_def.h>
30 #include <stddef.h>
31 #include <xlat_tables_arch.h>
32 #include <xlat_tables_defs.h>
33 
34 /* Parameters of register values required when enabling MMU */
35 extern uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
36 
37 /* Forward declaration */
38 struct mmap_region;
39 
40 /*
41  * Helper macro to define an mmap_region_t.  This macro allows to specify all
42  * the fields of the structure but its parameter list is not guaranteed to
43  * remain stable as we add members to mmap_region_t.
44  */
45 #define _MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)	\
46 	{							\
47 		.base_pa = (_pa),				\
48 		.base_va = (_va),				\
49 		.size = (_sz),					\
50 		.attr = (_attr),				\
51 		.granularity = (_gr),				\
52 	}
53 
54 /* Struct that holds all information about the translation tables. */
55 struct xlat_ctx {
56 	/*
57 	 * Max allowed Virtual and Physical Addresses.
58 	 */
59 	unsigned long long pa_max_address;
60 	uintptr_t va_max_address;
61 
62 	/*
63 	 * Array of all memory regions stored in order of ascending end address
64 	 * and ascending size to simplify the code that allows overlapping
65 	 * regions. The list is terminated by the first entry with size == 0.
66 	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
67 	 * array of mmap_num + 1 elements, so that there is space for the final
68 	 * null entry.
69 	 */
70 	struct mmap_region *mmap;
71 	unsigned int mmap_num;
72 
73 	/*
74 	 * Array of finer-grain translation tables.
75 	 * For example, if the initial lookup level is 1 then this array would
76 	 * contain both level-2 and level-3 entries.
77 	 */
78 	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
79 	unsigned int tables_num;
80 	/*
81 	 * Keep track of how many regions are mapped in each table. The base
82 	 * table can't be unmapped so it isn't needed to keep track of it.
83 	 */
84 #if PLAT_XLAT_TABLES_DYNAMIC
85 	int *tables_mapped_regions;
86 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
87 
88 	unsigned int next_table;
89 
90 	/*
91 	 * Base translation table. It doesn't need to have the same amount of
92 	 * entries as the ones used for other levels.
93 	 */
94 	uint64_t *base_table;
95 	unsigned int base_table_entries;
96 
97 	/*
98 	* Max Physical and Virtual addresses currently in use by the
99 	* translation tables. These might get updated as we map/unmap memory
100 	* regions but they will never go beyond pa/va_max_address.
101 	*/
102 	unsigned long long max_pa;
103 	uintptr_t max_va;
104 
105 	/* Level of the base translation table. */
106 	unsigned int base_level;
107 
108 	/* Set to 1 when the translation tables are initialized. */
109 	unsigned int initialized;
110 
111 	/*
112 	 * Translation regime managed by this xlat_ctx_t. It takes the values of
113 	 * the enumeration xlat_regime_t. The type is "int" to avoid a circular
114 	 * dependency on xlat_tables_v2.h, but this member must be treated as
115 	 * xlat_regime_t.
116 	 */
117 	int xlat_regime;
118 };
119 
120 #if PLAT_XLAT_TABLES_DYNAMIC
121 #define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
122 	static int _ctx_name##_mapped_regions[_xlat_tables_count];
123 
124 #define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
125 	.tables_mapped_regions = _ctx_name##_mapped_regions,
126 #else
127 #define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
128 	/* do nothing */
129 
130 #define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
131 	/* do nothing */
132 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
133 
134 #define _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, _xlat_tables_count,	\
135 			_virt_addr_space_size, _phy_addr_space_size,		\
136 			_xlat_regime, _section_name)				\
137 	CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),		\
138 		assert_invalid_virtual_addr_space_size_for_##_ctx_name);	\
139 										\
140 	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),		\
141 		assert_invalid_physical_addr_space_sizefor_##_ctx_name);	\
142 										\
143 	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];			\
144 										\
145 	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]		\
146 		[XLAT_TABLE_ENTRIES]						\
147 		__aligned(XLAT_TABLE_SIZE) __section(_section_name);		\
148 										\
149 	static uint64_t _ctx_name##_base_xlat_table				\
150 		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]		\
151 		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)	\
152 			* sizeof(uint64_t));					\
153 										\
154 	_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)			\
155 										\
156 	static xlat_ctx_t _ctx_name##_xlat_ctx = {				\
157 		.va_max_address = (_virt_addr_space_size) - 1,			\
158 		.pa_max_address = (_phy_addr_space_size) - 1,			\
159 		.mmap = _ctx_name##_mmap,					\
160 		.mmap_num = _mmap_count,					\
161 		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),	\
162 		.base_table = _ctx_name##_base_xlat_table,			\
163 		.base_table_entries =						\
164 			GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),	\
165 		.tables = _ctx_name##_xlat_tables,				\
166 		.tables_num = _xlat_tables_count,				\
167 		 _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
168 		.xlat_regime = (_xlat_regime),					\
169 		.max_pa = 0,							\
170 		.max_va = 0,							\
171 		.next_table = 0,						\
172 		.initialized = 0,						\
173 	}
174 
175 #endif /*__ASSEMBLY__*/
176 
177 #if AARCH64
178 
179 /*
180  * This IMAGE_EL macro must not to be used outside the library, and it is only
181  * used in AArch64.
182  */
183 #if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
184 # define IMAGE_EL	3
185 # define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME
186 #else
187 # define IMAGE_EL	1
188 # define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
189 #endif
190 
191 #else /* if AARCH32 */
192 
193 /*
194  * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in
195  * AArch64 except for the XN bits, but we set and unset them at the same time,
196  * so there's no difference in practice.
197  */
198 #define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
199 
200 #endif /* AARCH64 */
201 
202 #endif /* __XLAT_TABLES_V2_HELPERS_H__ */
203