blob: f5e310066fe2f7895c661554f4832286b6b94e76 [file] [log] [blame]
Sandrine Bailleux3120ea22017-07-10 13:37:48 +01001/*
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 */
28struct mmap_region;
29
30/* Struct that holds all information about the translation tables. */
31struct 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__ */