xlat_tables_v2_helpers.h 5.21 KB
Newer Older
1
/*
2
 * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3
4
5
6
7
8
9
10
11
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

/*
 * This header file contains internal definitions that are not supposed to be
 * used outside of this library code.
 */

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
12
13
#ifndef XLAT_TABLES_V2_HELPERS_H
#define XLAT_TABLES_V2_HELPERS_H
14

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
15
#ifndef XLAT_TABLES_V2_H
16
17
18
#error "Do not include this header file directly. Include xlat_tables_v2.h instead."
#endif

19
#ifndef __ASSEMBLER__
20

21
#include <stdbool.h>
22
#include <stddef.h>
23
24
25
26

#include <platform_def.h>

#include <lib/cassert.h>
27
#include <lib/utils_def.h>
28
29
#include <lib/xlat_tables/xlat_tables_arch.h>
#include <lib/xlat_tables/xlat_tables_defs.h>
30
31
32
33

/* Forward declaration */
struct mmap_region;

34
35
36
37
38
/*
 * Helper macro to define an mmap_region_t.  This macro allows to specify all
 * the fields of the structure but its parameter list is not guaranteed to
 * remain stable as we add members to mmap_region_t.
 */
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
39
#define MAP_REGION_FULL_SPEC(_pa, _va, _sz, _attr, _gr)		\
40
41
42
43
44
45
46
47
	{							\
		.base_pa = (_pa),				\
		.base_va = (_va),				\
		.size = (_sz),					\
		.attr = (_attr),				\
		.granularity = (_gr),				\
	}

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* Struct that holds all information about the translation tables. */
struct xlat_ctx {
	/*
	 * Max allowed Virtual and Physical Addresses.
	 */
	unsigned long long pa_max_address;
	uintptr_t va_max_address;

	/*
	 * Array of all memory regions stored in order of ascending end address
	 * and ascending size to simplify the code that allows overlapping
	 * regions. The list is terminated by the first entry with size == 0.
	 * The max size of the list is stored in `mmap_num`. `mmap` points to an
	 * array of mmap_num + 1 elements, so that there is space for the final
	 * null entry.
	 */
	struct mmap_region *mmap;
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
65
	int mmap_num;
66
67
68
69
70
71
72

	/*
	 * Array of finer-grain translation tables.
	 * For example, if the initial lookup level is 1 then this array would
	 * contain both level-2 and level-3 entries.
	 */
	uint64_t (*tables)[XLAT_TABLE_ENTRIES];
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
73
	int tables_num;
74
75
76
#if PLAT_RO_XLAT_TABLES
	bool readonly_tables;
#endif
77
78
79
80
81
82
83
84
	/*
	 * Keep track of how many regions are mapped in each table. The base
	 * table can't be unmapped so it isn't needed to keep track of it.
	 */
#if PLAT_XLAT_TABLES_DYNAMIC
	int *tables_mapped_regions;
#endif /* PLAT_XLAT_TABLES_DYNAMIC */

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
85
	int next_table;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104

	/*
	 * Base translation table. It doesn't need to have the same amount of
	 * entries as the ones used for other levels.
	 */
	uint64_t *base_table;
	unsigned int base_table_entries;

	/*
	* Max Physical and Virtual addresses currently in use by the
	* translation tables. These might get updated as we map/unmap memory
	* regions but they will never go beyond pa/va_max_address.
	*/
	unsigned long long max_pa;
	uintptr_t max_va;

	/* Level of the base translation table. */
	unsigned int base_level;

105
106
	/* Set to true when the translation tables are initialized. */
	bool initialized;
107
108

	/*
109
110
	 * Translation regime managed by this xlat_ctx_t. It should be one of
	 * the EL*_REGIME defines.
111
	 */
112
	int xlat_regime;
113
114
115
};

#if PLAT_XLAT_TABLES_DYNAMIC
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
116
#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
117
118
	static int _ctx_name##_mapped_regions[_xlat_tables_count];

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
119
#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)				\
120
121
	.tables_mapped_regions = _ctx_name##_mapped_regions,
#else
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
122
#define XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
123
124
	/* do nothing */

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
125
#define XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)				\
126
127
128
	/* do nothing */
#endif /* PLAT_XLAT_TABLES_DYNAMIC */

129
130
131
132
133
134
135
136
#if PLAT_RO_XLAT_TABLES
#define XLAT_CTX_INIT_TABLE_ATTR()					\
	.readonly_tables = false,
#else
#define XLAT_CTX_INIT_TABLE_ATTR()
	/* do nothing */
#endif

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
137
138
#define REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count,		\
			_xlat_tables_count, _virt_addr_space_size,	\
139
140
			_phy_addr_space_size, _xlat_regime,		\
			_table_section, _base_table_section)		\
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
141
142
143
144
145
146
147
	CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size),	\
		assert_invalid_physical_addr_space_sizefor_##_ctx_name);\
									\
	static mmap_region_t _ctx_name##_mmap[_mmap_count + 1];		\
									\
	static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count]	\
		[XLAT_TABLE_ENTRIES]					\
148
		__aligned(XLAT_TABLE_SIZE) __section(_table_section);	\
149
150
151
152
153
									\
	static uint64_t _ctx_name##_base_xlat_table			\
		[GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)]	\
		__aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)\
			* sizeof(uint64_t))				\
154
		__section(_base_table_section);				\
155
156
157
158
159
160
161
162
									\
	XLAT_ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count)		\
									\
	static xlat_ctx_t _ctx_name##_xlat_ctx = {			\
		.pa_max_address = (_phy_addr_space_size) - 1ULL,	\
		.va_max_address = (_virt_addr_space_size) - 1UL,	\
		.mmap = _ctx_name##_mmap,				\
		.mmap_num = (_mmap_count),				\
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
163
		.tables = _ctx_name##_xlat_tables,			\
164
		.tables_num = ARRAY_SIZE(_ctx_name##_xlat_tables),	\
165
		 XLAT_CTX_INIT_TABLE_ATTR()				\
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
166
		 XLAT_REGISTER_DYNMAP_STRUCT(_ctx_name)			\
167
168
169
		.next_table = 0,					\
		.base_table = _ctx_name##_base_xlat_table,		\
		.base_table_entries =					\
170
			ARRAY_SIZE(_ctx_name##_base_xlat_table),	\
Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
171
172
		.max_pa = 0U,						\
		.max_va = 0U,						\
173
		.base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size),\
174
		.initialized = false,					\
175
		.xlat_regime = (_xlat_regime)				\
176
177
	}

178
#endif /*__ASSEMBLER__*/
179

Antonio Nino Diaz's avatar
Antonio Nino Diaz committed
180
#endif /* XLAT_TABLES_V2_HELPERS_H */