blob: 56b9a93f4cfbc99ea729bcec2267642a93100b22 [file] [log] [blame]
Sandrine Bailleux3120ea22017-07-10 13:37:48 +01001/*
Jeenu Viswambharan58e81482018-04-27 15:06:57 +01002 * Copyright (c) 2017-2018, 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
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
Jeenu Viswambharan58e81482018-04-27 15:06:57 +010019/* 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
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010026#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
Jeenu Viswambharan58e81482018-04-27 15:06:57 +010034/* Parameters of register values required when enabling MMU */
35extern uint32_t mmu_cfg_params[MMU_CFG_PARAM_MAX];
36
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010037/* Forward declaration */
38struct mmap_region;
39
Sandrine Bailleux8f23fa82017-09-28 21:58:12 +010040/*
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
Sandrine Bailleux3120ea22017-07-10 13:37:48 +010054/* Struct that holds all information about the translation tables. */
55struct 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 /*
Antonio Nino Diazf1b84f62018-07-03 11:58:49 +0100112 * Translation regime managed by this xlat_ctx_t. It should be one of
113 * the EL*_REGIME defines.
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100114 */
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100115 int xlat_regime;
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100116};
117
118#if PLAT_XLAT_TABLES_DYNAMIC
119#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
120 static int _ctx_name##_mapped_regions[_xlat_tables_count];
121
122#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \
123 .tables_mapped_regions = _ctx_name##_mapped_regions,
124#else
125#define _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
126 /* do nothing */
127
128#define _REGISTER_DYNMAP_STRUCT(_ctx_name) \
129 /* do nothing */
130#endif /* PLAT_XLAT_TABLES_DYNAMIC */
131
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100132#define _REGISTER_XLAT_CONTEXT_FULL_SPEC(_ctx_name, _mmap_count, _xlat_tables_count, \
133 _virt_addr_space_size, _phy_addr_space_size, \
Antonio Nino Diaz086fbd62017-11-17 11:48:55 +0000134 _xlat_regime, _section_name) \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100135 CASSERT(CHECK_VIRT_ADDR_SPACE_SIZE(_virt_addr_space_size), \
136 assert_invalid_virtual_addr_space_size_for_##_ctx_name); \
137 \
138 CASSERT(CHECK_PHY_ADDR_SPACE_SIZE(_phy_addr_space_size), \
139 assert_invalid_physical_addr_space_sizefor_##_ctx_name); \
140 \
141 static mmap_region_t _ctx_name##_mmap[_mmap_count + 1]; \
142 \
143 static uint64_t _ctx_name##_xlat_tables[_xlat_tables_count] \
144 [XLAT_TABLE_ENTRIES] \
Antonio Nino Diaz086fbd62017-11-17 11:48:55 +0000145 __aligned(XLAT_TABLE_SIZE) __section(_section_name); \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100146 \
147 static uint64_t _ctx_name##_base_xlat_table \
148 [GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size)] \
149 __aligned(GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size) \
150 * sizeof(uint64_t)); \
151 \
152 _ALLOC_DYNMAP_STRUCT(_ctx_name, _xlat_tables_count) \
153 \
154 static xlat_ctx_t _ctx_name##_xlat_ctx = { \
155 .va_max_address = (_virt_addr_space_size) - 1, \
156 .pa_max_address = (_phy_addr_space_size) - 1, \
157 .mmap = _ctx_name##_mmap, \
Antonio Nino Diazf1b84f62018-07-03 11:58:49 +0100158 .mmap_num = (_mmap_count), \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100159 .base_level = GET_XLAT_TABLE_LEVEL_BASE(_virt_addr_space_size), \
160 .base_table = _ctx_name##_base_xlat_table, \
161 .base_table_entries = \
162 GET_NUM_BASE_LEVEL_ENTRIES(_virt_addr_space_size), \
163 .tables = _ctx_name##_xlat_tables, \
164 .tables_num = _xlat_tables_count, \
165 _REGISTER_DYNMAP_STRUCT(_ctx_name) \
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100166 .xlat_regime = (_xlat_regime), \
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100167 .max_pa = 0, \
168 .max_va = 0, \
169 .next_table = 0, \
170 .initialized = 0, \
171 }
172
Jeenu Viswambharan58e81482018-04-27 15:06:57 +0100173#endif /*__ASSEMBLY__*/
174
Antonio Nino Diazd017bcc2017-10-16 15:25:22 +0100175#if AARCH64
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100176
Antonio Nino Diazd017bcc2017-10-16 15:25:22 +0100177/*
178 * This IMAGE_EL macro must not to be used outside the library, and it is only
179 * used in AArch64.
180 */
Roberto Vargase0e99462017-10-30 14:43:43 +0000181#if defined(IMAGE_BL1) || defined(IMAGE_BL31) || (defined(IMAGE_BL2) && BL2_AT_EL3)
Antonio Nino Diazdcf9d922017-10-04 16:52:15 +0100182# define IMAGE_EL 3
183# define IMAGE_XLAT_DEFAULT_REGIME EL3_REGIME
184#else
185# define IMAGE_EL 1
186# define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
187#endif
188
Antonio Nino Diazd017bcc2017-10-16 15:25:22 +0100189#else /* if AARCH32 */
190
191/*
192 * The PL1&0 translation regime in AArch32 behaves like the EL1&0 regime in
193 * AArch64 except for the XN bits, but we set and unset them at the same time,
194 * so there's no difference in practice.
195 */
196#define IMAGE_XLAT_DEFAULT_REGIME EL1_EL0_REGIME
197
198#endif /* AARCH64 */
199
Sandrine Bailleux3120ea22017-07-10 13:37:48 +0100200#endif /* __XLAT_TABLES_V2_HELPERS_H__ */