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