1 #ifndef __RV_SV39_H__
2 #define __RV_SV39_H__
3
4 #include <stdint.h>
5 #include <stddef.h>
6 #include <compiler/compiler_gcc.h>
7
8 #define SV39_VPN2(va) (((va) >> (9 + 9 + 12)) & 0x1FF)
9 #define SV39_VPN1(va) (((va) >> (0 + 9 + 12)) & 0x1FF)
10 #define SV39_VPN0(va) (((va) >> (0 + 0 + 12)) & 0x1FF)
11
12 #define SV39_PA2PPN(pa) (((pa) >> (0 + 0 + 12)) & 0xFFFFFFFFFF)
13 #define SV39_PTE2PPN(pte) (((pte) >> (10)) & 0xFFFFFFF)
14 #define SV39_PTE2PA(pte) ((uint64_t)(SV39_PTE2PPN(pte) << 12))
15
16 #define SV39_JTLB_ENTRY_CNT (256)
17
18 /* SMCIR */
19 #define SMCIR_ASID_OFFSET (0)
20 #define SMCIR_ASID_LEN (16)
21
22 #define SMCIR_TLBII_OFFSET (25)
23 #define SMCIR_TLBII_LEN (1)
24 #define SMCIR_TLBII (1 << 25)
25
26 #define SMCIR_TLBIALL_OFFSET (26)
27 #define SMCIR_TLBIALL_LEN (1)
28 #define SMCIR_TLBIALL (1 << 26)
29
30 #define SMCIR_TLBIASID_OFFSET (27)
31 #define SMCIR_TLBIASID_LEN (1)
32 #define SMCIR_TLBIASID (1 << 27)
33
34 #define SMCIR_TLBWR_OFFSET (28)
35 #define SMCIR_TLBWR_LEN (1)
36 #define SMCIR_TLBWR (1 << 28)
37
38 #define SMCIR_TLBWI_OFFSET (29)
39 #define SMCIR_TLBWI_LEN (1)
40 #define SMCIR_TLBWI (1 << 29)
41
42 #define SMCIR_TLBR_OFFSET (30)
43 #define SMCIR_TLBR_LEN (1)
44 #define SMCIR_TLBR (1 << 30)
45
46 #define SMCIR_TLBP_OFFSET (31)
47 #define SMCIR_TLBP_LEN (1)
48 #define SMCIR_TLBP (1 << 31)
49
50 /* SMIR */
51 #define SMIR_INDEX_OFFSET (0)
52 #define SMIR_INDEX_LEN (9)
53
54 #define SMCIR_T_OFFSET (30)
55 #define SMCIR_TF_LEN (1)
56 #define SMCIR_TF (1 << 30)
57
58 #define SMCIR_P_OFFSET (31)
59 #define SMCIR_PF_LEN (1)
60 #define SMCIR_PF (1 << 31)
61
62 /* SMEH */
63 #define SMEH_ASID_OFFSET (0)
64 #define SMEH_ASID_LEN (16)
65
66 #define SMEH_PAGESIZE_OFFSET (16)
67 #define SMEH_PAGESIZE_LEN (3)
68 #define SMEH_PAGESIZE_4KB (1 << 16)
69 #define SMEH_PAGESIZE_2MB (2 << 16)
70 #define SMEH_PAGESIZE_1GB (4 << 16)
71
72 #define SMEH_VPN_OFFSET (19)
73 #define SMEH_VPN_LEN (27)
74
75 #undef PTE_V
76 #undef PTE_U
77 #undef PTE_G
78 #undef PTE_A
79 #undef PTE_D
80
81 /* SMEL & PTE */
82 #define PTE_V_OFFSET (0)
83 #define PTE_V_LEN (1)
84 #define PTE_V (1 << 0)
85
86 #define PTE_R_OFFSET (1)
87 #define PTE_R_LEN (1)
88
89 #define PTE_W_OFFSET (2)
90 #define PTE_W_LEN (1)
91
92 #define PTE_X_OFFSET (3)
93 #define PTE_X_LEN (1)
94
95 #define PTE_XWR_MASK (~(0xE))
96 #define PTE_XWR_NEXT (0 << 1)
97 #define PTE_XWR_RO_PAGE (1 << 1)
98 #define PTE_XWR_WR_PAGE (3 << 1)
99 #define PTE_XWR_XO_PAGE (4 << 1)
100 #define PTE_XWR_XR_PAGE (5 << 1)
101 #define PTE_XWR_XWR_PAGE (7 << 1)
102
103 #define PTE_U_OFFSET (4)
104 #define PTE_U_LEN (1)
105 #define PTE_U (1 << 4)
106
107 #define PTE_G_OFFSET (5)
108 #define PTE_G_LEN (1)
109 #define PTE_G (1 << 5)
110
111 #define PTE_A_OFFSET (6)
112 #define PTE_A_LEN (1)
113 #define PTE_A (1 << 6)
114
115 #define PTE_D_OFFSET (7)
116 #define PTE_D_LEN (1)
117 #define PTE_D (1 << 7)
118
119 #define SMEL_PPN_OFFSET (8)
120 #define PTE_PPN_OFFSET (10)
121 #define PTE_PPN_LEN (28)
122
123 #define PTE_SEC_OFFSET (59)
124 #define PTE_SEC_LEN (1)
125
126 #define PTE_B_OFFSET (61)
127 #define PTE_B_LEN (1)
128 #define PTE_B ((uintptr_t)1 << 61)
129
130 #define PTE_C_OFFSET (62)
131 #define PTE_C_LEN (1)
132 #define PTE_C ((uintptr_t)1 << 62)
133
134 #define PTE_SO_OFFSET (63)
135 #define PTE_SO_LEN (1)
136 #define PTE_SO ((uintptr_t)1 << 63)
137
138 /* SATP */
139 #define SATP_PPN_OFFSET (0)
140 #define SATP_PPN_LEN (28)
141
142 #define SATP_ASID_OFFSET (44)
143 #define SATP_ASID_LEN (16)
144
145 #define SATP_MODE_OFFSET (60)
146 #define SATP_MODE_LEN (4)
147 #define SATP_MODE_SV39 ((uintptr_t)8 << 60)
148
149 typedef enum {
150 Sv39_PAGESIZE_4KB = SMEH_PAGESIZE_4KB,
151 Sv39_PAGESIZE_2MB = SMEH_PAGESIZE_2MB,
152 Sv39_PAGESIZE_1GB = SMEH_PAGESIZE_1GB,
153 Sv39_PAGESIZE_NUM,
154 Sv39_PAGESIZE_MAX = 0x7FFFFFFFFFFFFFFF
155 } Sv39_PAGESIZE_Type;
156
157 typedef enum {
158 Sv39_PTE_LOC_JTLB = 0,
159 Sv39_PTE_LOC_PAGETABLE,
160 Sv39_PTE_LOC_NUM,
161 Sv39_PTE_LOC_MAX = 0x7FFFFFFFFFFFFFFF
162 } Sv39_PTE_LOC_Type;
163
164 typedef struct _Sv39_PTE_cfg {
165 uintptr_t va;
166 uintptr_t pa;
167 Sv39_PAGESIZE_Type size;
168 uintptr_t flags;
169 uintptr_t asid;
170 Sv39_PTE_LOC_Type where;
171 uintptr_t tlb_entry;
172 } Sv39_PTE_cfg_t;
173
RV_Sv39_INVALID_VMA(void)174 __ALWAYS_STATIC_INLINE void RV_Sv39_INVALID_VMA(void)
175 {
176 __asm volatile("fence"
177 :
178 :
179 : "memory");
180 __asm volatile("sfence.vma x0,x0"
181 :
182 :
183 : "memory");
184 __asm volatile("fence"
185 :
186 :
187 : "memory");
188 }
189
RV_Sv39_Set_SMCIR(uintptr_t smcir)190 __ALWAYS_STATIC_INLINE void RV_Sv39_Set_SMCIR(uintptr_t smcir)
191 {
192 __asm volatile("csrw smcir, %0"
193 :
194 : "r"(smcir)
195 : "memory");
196 }
197
RV_Sv39_Get_SMIR(void)198 __ALWAYS_STATIC_INLINE uintptr_t RV_Sv39_Get_SMIR(void)
199 {
200 uintptr_t result;
201
202 __asm volatile("csrr %0, smir"
203 : "=r"(result)
204 :
205 : "memory");
206 return (result);
207 }
208
RV_Sv39_Set_SMIR(uintptr_t smir)209 __ALWAYS_STATIC_INLINE void RV_Sv39_Set_SMIR(uintptr_t smir)
210 {
211 __asm volatile("csrw smir, %0"
212 :
213 : "r"(smir)
214 : "memory");
215 }
216
RV_Sv39_Set_SATP(uintptr_t asid,uintptr_t * ppn)217 __ALWAYS_STATIC_INLINE void RV_Sv39_Set_SATP(uintptr_t asid, uintptr_t *ppn)
218 {
219 __asm volatile("csrw satp, %0"
220 :
221 : "r"(SATP_MODE_SV39 | (asid << SATP_ASID_OFFSET) | ((uintptr_t)(ppn) >> 12))
222 : "memory");
223 }
224
225 /* cache config into jTLB, return tlb index if success */
226 int RV_Sv39_Create_PageMapping(Sv39_PTE_cfg_t *cfg, uintptr_t *tlb_index, volatile uintptr_t *ttb0);
227
228 #endif /* __RV_SV39_H__ */
229