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