xref: /rk3399_ARM-atf/include/lib/xlat_tables/xlat_tables_v2_helpers.h (revision 7bba6884a0112ec38ad5992b1eb3f0398abf5cf7)
1 /*
2  * Copyright (c) 2017, 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 #ifndef __ASSEMBLY__
20 
21 #include <cassert.h>
22 #include <platform_def.h>
23 #include <stddef.h>
24 #include <xlat_tables_arch.h>
25 #include <xlat_tables_defs.h>
26 
27 /* Forward declaration */
28 struct mmap_region;
29 
30 /* Struct that holds all information about the translation tables. */
31 struct xlat_ctx {
32 	/*
33 	 * Max allowed Virtual and Physical Addresses.
34 	 */
35 	unsigned long long pa_max_address;
36 	uintptr_t va_max_address;
37 
38 	/*
39 	 * Array of all memory regions stored in order of ascending end address
40 	 * and ascending size to simplify the code that allows overlapping
41 	 * regions. The list is terminated by the first entry with size == 0.
42 	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
43 	 * array of mmap_num + 1 elements, so that there is space for the final
44 	 * null entry.
45 	 */
46 	struct mmap_region *mmap;
47 	unsigned int mmap_num;
48 
49 	/*
50 	 * Array of finer-grain translation tables.
51 	 * For example, if the initial lookup level is 1 then this array would
52 	 * contain both level-2 and level-3 entries.
53 	 */
54 	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
55 	unsigned int tables_num;
56 	/*
57 	 * Keep track of how many regions are mapped in each table. The base
58 	 * table can't be unmapped so it isn't needed to keep track of it.
59 	 */
60 #if PLAT_XLAT_TABLES_DYNAMIC
61 	int *tables_mapped_regions;
62 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
63 
64 	unsigned int next_table;
65 
66 	/*
67 	 * Base translation table. It doesn't need to have the same amount of
68 	 * entries as the ones used for other levels.
69 	 */
70 	uint64_t *base_table;
71 	unsigned int base_table_entries;
72 
73 	/*
74 	* Max Physical and Virtual addresses currently in use by the
75 	* translation tables. These might get updated as we map/unmap memory
76 	* regions but they will never go beyond pa/va_max_address.
77 	*/
78 	unsigned long long max_pa;
79 	uintptr_t max_va;
80 
81 	/* Level of the base translation table. */
82 	unsigned int base_level;
83 
84 	/* Set to 1 when the translation tables are initialized. */
85 	unsigned int initialized;
86 
87 	/*
88 	 * Bit mask that has to be ORed to the rest of a translation table
89 	 * descriptor in order to prohibit execution of code at the exception
90 	 * level of this translation context.
91 	 */
92 	uint64_t execute_never_mask;
93 };
94 
95 #if PLAT_XLAT_TABLES_DYNAMIC
96 #define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
97 	static int _ctx_name##_mapped_regions[_xlat_tables_count];
98 
99 #define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
100 	.tables_mapped_regions = _ctx_name##_mapped_regions,
101 #else
102 #define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
103 	/* do nothing */
104 
105 #define _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
106 	/* do nothing */
107 #endif /* PLAT_XLAT_TABLES_DYNAMIC */
108 
109 
110 #define _REGISTER_XLAT_CONTEXT(_ctx_name, _mmap_count, _xlat_tables_count,	\
111 			_virt_addr_space_size, _phy_addr_space_size)		\
112 	CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size),		\
113 		assert_invalid_virtual_addr_space_size_for_##_ctx_name);	\
114 										\
115 	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),		\
116 		assert_invalid_physical_addr_space_sizefor_##_ctx_name);	\
117 										\
118 	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];			\
119 										\
120 	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]		\
121 		[XLAT_TABLE_ENTRIES]						\
122 		__aligned(XLAT_TABLE_SIZE) __section("xlat_table");		\
123 										\
124 	static uint64_t _ctx_name##_base_xlat_table				\
125 		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]		\
126 		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)	\
127 			* sizeof(uint64_t));					\
128 										\
129 	_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)			\
130 										\
131 	static xlat_ctx_t _ctx_name##_xlat_ctx = {				\
132 		.va_max_address = (_virt_addr_space_size) - 1,			\
133 		.pa_max_address = (_phy_addr_space_size) - 1,			\
134 		.mmap = _ctx_name##_mmap,					\
135 		.mmap_num = _mmap_count,					\
136 		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),	\
137 		.base_table = _ctx_name##_base_xlat_table,			\
138 		.base_table_entries =						\
139 			GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size),	\
140 		.tables = _ctx_name##_xlat_tables,				\
141 		.tables_num = _xlat_tables_count,				\
142 		 _REGISTER_DYNMAP_STRUCT(_ctx_name)				\
143 		.max_pa = 0,							\
144 		.max_va = 0,							\
145 		.next_table = 0,						\
146 		.initialized = 0,						\
147 	}
148 
149 #endif /*__ASSEMBLY__*/
150 
151 #endif /* __XLAT_TABLES_V2_HELPERS_H__ */
152