1 /*
2 * SPDX-License-Identifier: BSD-3-Clause
3 * SPDX-FileCopyrightText: Copyright TF-RMM Contributors.
4 */
5
6 #ifndef TABLE_H
7 #define TABLE_H
8
9 #include <arch_features.h>
10 #include <memory.h>
11
12 #define MIN_IPA_BITS 32
13 #define MAX_IPA_BITS 48
14 #define MAX_IPA_SIZE (1UL << MAX_IPA_BITS)
15
16 #define MIN_STARTING_LEVEL 0
17 #define RTT_PAGE_LEVEL 3
18 #define RTT_MIN_BLOCK_LEVEL 2
19
20 /* TODO: Fix this when introducing LPA2 support */
21 COMPILER_ASSERT(MIN_STARTING_LEVEL >= 0);
22
23 /* TODO: Allow the NS caller to select the stage 2 starting level */
24 #define RTT_STARTING_LEVEL 0
25
26 /*
27 * S2TTE_STRIDE: The number of bits resolved in a single level of translation
28 * walk (except for the starting level which may resolve more or fewer bits).
29 */
30 #define S2TTE_STRIDE (GRANULE_SHIFT - 3)
31 #define S2TTES_PER_S2TT (1 << S2TTE_STRIDE)
32
33 struct rd;
34 enum ripas;
35
36 unsigned long s2tte_create_ripas(enum ripas ripas);
37 unsigned long s2tte_create_unassigned(enum ripas ripas);
38 unsigned long s2tte_create_destroyed(void);
39 unsigned long s2tte_create_assigned_empty(unsigned long pa, long level);
40 unsigned long s2tte_create_valid(unsigned long pa, long level);
41 unsigned long s2tte_create_invalid_ns(void);
42 unsigned long s2tte_create_valid_ns(unsigned long s2tte, long level);
43 unsigned long s2tte_create_table(unsigned long pa, long level);
44
45 bool host_ns_s2tte_is_valid(unsigned long s2tte, long level);
46 unsigned long host_ns_s2tte(unsigned long s2tte, long level);
47
48 bool s2tte_is_unassigned(unsigned long s2tte);
49 bool s2tte_is_destroyed(unsigned long s2tte);
50 bool s2tte_is_assigned(unsigned long s2tte, long level);
51 bool s2tte_is_valid(unsigned long s2tte, long level);
52 bool s2tte_is_valid_ns(unsigned long s2tte, long level);
53 bool s2tte_is_table(unsigned long s2tte, long level);
54
55 enum ripas s2tte_get_ripas(unsigned long s2tte);
56
57 void s2tt_init_unassigned(unsigned long *s2tt, enum ripas ripas);
58 void s2tt_init_destroyed(unsigned long *s2tt);
59 void s2tt_init_assigned_empty(unsigned long *s2tt, unsigned long pa, long level);
60 void s2tt_init_valid(unsigned long *s2tt, unsigned long pa, long level);
61 void s2tt_init_valid_ns(unsigned long *s2tt, unsigned long pa, long level);
62
63 unsigned long s2tte_pa(unsigned long s2tte, long level);
64 unsigned long s2tte_pa_table(unsigned long s2tte, long level);
65 bool addr_is_level_aligned(unsigned long addr, long level);
66 bool addr_block_intersects_par(struct rd *rd, unsigned long addr, long level);
67 unsigned long s2tte_map_size(int level);
68
69 struct realm_s2_context;
70 void invalidate_page(const struct realm_s2_context *ctx, unsigned long addr);
71 void invalidate_block(const struct realm_s2_context *ctx, unsigned long addr);
72 void invalidate_pages_in_block(const struct realm_s2_context *ctx, unsigned long addr);
73
74 bool table_is_unassigned_block(unsigned long *table, enum ripas *ripas);
75 bool table_is_destroyed_block(unsigned long *table);
76
77 bool table_maps_assigned_block(unsigned long *table, long level);
78 bool table_maps_valid_block(unsigned long *table, long level);
79 bool table_maps_valid_ns_block(unsigned long *table, long level);
80
81 struct rtt_walk {
82 struct granule *g_llt;
83 unsigned long index;
84 long last_level;
85 };
86
87 void rtt_walk_lock_unlock(struct granule *g_root,
88 int start_level,
89 unsigned long ipa_bits,
90 unsigned long map_addr,
91 long level,
92 struct rtt_walk *wi);
93
94 /*
95 * The MMU is a separate observer, and requires that translation table updates
96 * are made with single-copy-atomic stores, necessitating inline assembly. For
97 * consistency we use accessors for both reads and writes of translation table
98 * entries.
99 */
__tte_write(uint64_t * ttep,uint64_t tte)100 static inline void __tte_write(uint64_t *ttep, uint64_t tte)
101 {
102 SCA_WRITE64(ttep, tte);
103 dsb(ish);
104 }
105 #define s1tte_write(s1ttep, s1tte) __tte_write(s1ttep, s1tte)
106 #define s2tte_write(s2ttep, s2tte) __tte_write(s2ttep, s2tte)
107
__tte_read(uint64_t * ttep)108 static inline uint64_t __tte_read(uint64_t *ttep)
109 {
110 return SCA_READ64(ttep);
111 }
112 #define s1tte_read(s1ttep) __tte_read(s1ttep)
113 #define s2tte_read(s2ttep) __tte_read(s2ttep)
114
max_ipa_size(void)115 static inline unsigned int max_ipa_size(void)
116 {
117 return arch_feat_get_pa_width();
118 }
119
120 #endif /* TABLE_H */
121