1 /*
2 * Copyright (c) 2021-2022 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7 #include "hpm_pmp_drv.h"
8 #include "hpm_csr_drv.h"
9
read_pmp_cfg(uint32_t idx)10 uint32_t read_pmp_cfg(uint32_t idx)
11 {
12 uint32_t pmp_cfg = 0;
13 switch (idx) {
14 case 0:
15 pmp_cfg = read_csr(CSR_PMPCFG0);
16 break;
17 case 1:
18 pmp_cfg = read_csr(CSR_PMPCFG1);
19 break;
20 case 2:
21 pmp_cfg = read_csr(CSR_PMPCFG2);
22 break;
23 case 3:
24 pmp_cfg = read_csr(CSR_PMPCFG3);
25 break;
26 default:
27 /* Do nothing */
28 break;
29 }
30 return pmp_cfg;
31 }
32
write_pmp_cfg(uint32_t value,uint32_t idx)33 void write_pmp_cfg(uint32_t value, uint32_t idx)
34 {
35 switch (idx) {
36 case 0:
37 write_csr(CSR_PMPCFG0, value);
38 break;
39 case 1:
40 write_csr(CSR_PMPCFG1, value);
41 break;
42 case 2:
43 write_csr(CSR_PMPCFG2, value);
44 break;
45 case 3:
46 write_csr(CSR_PMPCFG3, value);
47 break;
48 default:
49 /* Do nothing */
50 break;
51 }
52 }
53
write_pmp_addr(uint32_t value,uint32_t idx)54 void write_pmp_addr(uint32_t value, uint32_t idx)
55 {
56 switch (idx) {
57 case 0:
58 write_csr(CSR_PMPADDR0, value);
59 break;
60 case 1:
61 write_csr(CSR_PMPADDR1, value);
62 break;
63 case 2:
64 write_csr(CSR_PMPADDR2, value);
65 break;
66 case 3:
67 write_csr(CSR_PMPADDR3, value);
68 break;
69 case 4:
70 write_csr(CSR_PMPADDR4, value);
71 break;
72 case 5:
73 write_csr(CSR_PMPADDR5, value);
74 break;
75 case 6:
76 write_csr(CSR_PMPADDR6, value);
77 break;
78 case 7:
79 write_csr(CSR_PMPADDR7, value);
80 break;
81 case 8:
82 write_csr(CSR_PMPADDR8, value);
83 break;
84 case 9:
85 write_csr(CSR_PMPADDR9, value);
86 break;
87 case 10:
88 write_csr(CSR_PMPADDR10, value);
89 break;
90 case 11:
91 write_csr(CSR_PMPADDR11, value);
92 break;
93 case 12:
94 write_csr(CSR_PMPADDR12, value);
95 break;
96 case 13:
97 write_csr(CSR_PMPADDR13, value);
98 break;
99 case 14:
100 write_csr(CSR_PMPADDR14, value);
101 break;
102 case 15:
103 write_csr(CSR_PMPADDR15, value);
104 break;
105 default:
106 /* Do nothing */
107 break;
108 }
109 }
110
read_pmp_addr(uint32_t idx)111 uint32_t read_pmp_addr(uint32_t idx)
112 {
113 uint32_t ret_val = 0;
114 switch (idx) {
115 case 0:
116 ret_val = read_csr(CSR_PMPADDR0);
117 break;
118 case 1:
119 ret_val = read_csr(CSR_PMPADDR1);
120 break;
121 case 2:
122 ret_val = read_csr(CSR_PMPADDR2);
123 break;
124 case 3:
125 ret_val = read_csr(CSR_PMPADDR3);
126 break;
127 case 4:
128 ret_val = read_csr(CSR_PMPADDR4);
129 break;
130 case 5:
131 ret_val = read_csr(CSR_PMPADDR5);
132 break;
133 case 6:
134 ret_val = read_csr(CSR_PMPADDR6);
135 break;
136 case 7:
137 ret_val = read_csr(CSR_PMPADDR7);
138 break;
139 case 8:
140 ret_val = read_csr(CSR_PMPADDR8);
141 break;
142 case 9:
143 ret_val = read_csr(CSR_PMPADDR9);
144 break;
145 case 10:
146 ret_val = read_csr(CSR_PMPADDR10);
147 break;
148 case 11:
149 ret_val = read_csr(CSR_PMPADDR11);
150 break;
151 case 12:
152 ret_val = read_csr(CSR_PMPADDR12);
153 break;
154 case 13:
155 ret_val = read_csr(CSR_PMPADDR13);
156 break;
157 case 14:
158 ret_val = read_csr(CSR_PMPADDR14);
159 break;
160 case 15:
161 ret_val = read_csr(CSR_PMPADDR15);
162 break;
163 default:
164 /* Do nothing */
165 break;
166 }
167 return ret_val;
168 }
169
170 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
read_pma_cfg(uint32_t idx)171 uint32_t read_pma_cfg(uint32_t idx)
172 {
173 uint32_t pma_cfg = 0;
174 switch (idx) {
175 case 0:
176 pma_cfg = read_csr(CSR_PMACFG0);
177 break;
178 case 1:
179 pma_cfg = read_csr(CSR_PMACFG1);
180 break;
181 case 2:
182 pma_cfg = read_csr(CSR_PMACFG2);
183 break;
184 case 3:
185 pma_cfg = read_csr(CSR_PMACFG3);
186 break;
187 default:
188 /* Do nothing */
189 break;
190 }
191 return pma_cfg;
192 }
193
write_pma_cfg(uint32_t value,uint32_t idx)194 void write_pma_cfg(uint32_t value, uint32_t idx)
195 {
196 switch (idx) {
197 case 0:
198 write_csr(CSR_PMACFG0, value);
199 break;
200 case 1:
201 write_csr(CSR_PMACFG1, value);
202 break;
203 case 2:
204 write_csr(CSR_PMACFG2, value);
205 break;
206 case 3:
207 write_csr(CSR_PMACFG3, value);
208 break;
209 default:
210 /* Do nothing */
211 break;
212 }
213 }
write_pma_addr(uint32_t value,uint32_t idx)214 void write_pma_addr(uint32_t value, uint32_t idx)
215 {
216 switch (idx) {
217 case 0:
218 write_csr(CSR_PMAADDR0, value);
219 break;
220 case 1:
221 write_csr(CSR_PMAADDR1, value);
222 break;
223 case 2:
224 write_csr(CSR_PMAADDR2, value);
225 break;
226 case 3:
227 write_csr(CSR_PMAADDR3, value);
228 break;
229 case 4:
230 write_csr(CSR_PMAADDR4, value);
231 break;
232 case 5:
233 write_csr(CSR_PMAADDR5, value);
234 break;
235 case 6:
236 write_csr(CSR_PMAADDR6, value);
237 break;
238 case 7:
239 write_csr(CSR_PMAADDR7, value);
240 break;
241 case 8:
242 write_csr(CSR_PMAADDR8, value);
243 break;
244 case 9:
245 write_csr(CSR_PMAADDR9, value);
246 break;
247 case 10:
248 write_csr(CSR_PMAADDR10, value);
249 break;
250 case 11:
251 write_csr(CSR_PMAADDR11, value);
252 break;
253 case 12:
254 write_csr(CSR_PMAADDR12, value);
255 break;
256 case 13:
257 write_csr(CSR_PMAADDR13, value);
258 break;
259 case 14:
260 write_csr(CSR_PMAADDR14, value);
261 break;
262 case 15:
263 write_csr(CSR_PMAADDR15, value);
264 break;
265 default:
266 /* Do nothing */
267 break;
268 }
269 }
270
read_pma_addr(uint32_t idx)271 uint32_t read_pma_addr(uint32_t idx)
272 {
273 uint32_t ret_val = 0;
274 switch (idx) {
275 case 0:
276 ret_val = read_csr(CSR_PMAADDR0);
277 break;
278 case 1:
279 ret_val = read_csr(CSR_PMAADDR1);
280 break;
281 case 2:
282 ret_val = read_csr(CSR_PMAADDR2);
283 break;
284 case 3:
285 ret_val = read_csr(CSR_PMAADDR3);
286 break;
287 case 4:
288 ret_val = read_csr(CSR_PMAADDR4);
289 break;
290 case 5:
291 ret_val = read_csr(CSR_PMAADDR5);
292 break;
293 case 6:
294 ret_val = read_csr(CSR_PMAADDR6);
295 break;
296 case 7:
297 ret_val = read_csr(CSR_PMAADDR7);
298 break;
299 case 8:
300 ret_val = read_csr(CSR_PMAADDR8);
301 break;
302 case 9:
303 ret_val = read_csr(CSR_PMAADDR9);
304 break;
305 case 10:
306 ret_val = read_csr(CSR_PMAADDR10);
307 break;
308 case 11:
309 ret_val = read_csr(CSR_PMAADDR11);
310 break;
311 case 12:
312 ret_val = read_csr(CSR_PMAADDR12);
313 break;
314 case 13:
315 ret_val = read_csr(CSR_PMAADDR13);
316 break;
317 case 14:
318 ret_val = read_csr(CSR_PMAADDR14);
319 break;
320 case 15:
321 ret_val = read_csr(CSR_PMAADDR15);
322 break;
323 default:
324 /* Do nothing */
325 break;
326 }
327 return ret_val;
328 }
329 #endif /* #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1)) */
330
pmp_config_entry(const pmp_entry_t * entry,uint32_t entry_index)331 hpm_stat_t pmp_config_entry(const pmp_entry_t *entry, uint32_t entry_index)
332 {
333 hpm_stat_t status = status_invalid_argument;
334 do {
335 HPM_BREAK_IF((entry == NULL) || (entry_index > 15U));
336
337 uint32_t idx = entry_index / 4;
338 uint32_t offset = (entry_index * 8) & 0x1F;
339
340 uint32_t pmp_cfg = read_pmp_cfg(idx);
341 pmp_cfg &= ~(0xFFUL << offset);
342 pmp_cfg |= ((uint32_t) entry->pmp_cfg.val) << offset;
343 write_pmp_addr(entry->pmp_addr, entry_index);
344 write_pmp_cfg(pmp_cfg, idx);
345 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
346 uint32_t pma_cfg = read_pma_cfg(idx);
347 pma_cfg &= ~(0xFFUL << offset);
348 pma_cfg |= ((uint32_t) entry->pma_cfg.val) << offset;
349 write_pma_cfg(pma_cfg, idx);
350 write_pma_addr(entry->pma_addr, entry_index);
351 #endif
352 fencei();
353
354 status = status_success;
355
356 } while (false);
357
358 return status;
359 }
360
pmp_config(const pmp_entry_t * entry,uint32_t num_of_entries)361 hpm_stat_t pmp_config(const pmp_entry_t *entry, uint32_t num_of_entries)
362 {
363 hpm_stat_t status = status_invalid_argument;
364 do {
365 HPM_BREAK_IF((entry == NULL) || (num_of_entries < 1U) || (num_of_entries > 15U));
366
367 for (uint32_t i = 0; i < num_of_entries; i++) {
368 uint32_t idx = i / 4;
369 uint32_t offset = (i * 8) & 0x1F;
370 uint32_t pmp_cfg = read_pmp_cfg(idx);
371 pmp_cfg &= ~(0xFFUL << offset);
372 pmp_cfg |= ((uint32_t) entry->pmp_cfg.val) << offset;
373 write_pmp_addr(entry->pmp_addr, i);
374 write_pmp_cfg(pmp_cfg, idx);
375 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
376 uint32_t pma_cfg = read_pma_cfg(idx);
377 pma_cfg &= ~(0xFFUL << offset);
378 pma_cfg |= ((uint32_t) entry->pma_cfg.val) << offset;
379 write_pma_cfg(pma_cfg, idx);
380 write_pma_addr(entry->pma_addr, i);
381 #endif
382 ++entry;
383 }
384 fencei();
385
386 status = status_success;
387
388 } while (false);
389
390 return status;
391 }
392
pmp_disable(void)393 void pmp_disable(void)
394 {
395 /* Disable caches */
396 fencei();
397 uint32_t mcache_ctl = read_csr(CSR_MCACHE_CTL);
398 write_csr(CSR_MCACHE_CTL, 0x0);
399 fencei();
400
401 write_csr(CSR_PMPCFG0, 0);
402 write_csr(CSR_PMPCFG1, 0);
403 write_csr(CSR_PMPCFG2, 0);
404 write_csr(CSR_PMPCFG3, 0);
405 write_csr(CSR_PMPADDR0, 0);
406 write_csr(CSR_PMPADDR1, 0);
407 write_csr(CSR_PMPADDR2, 0);
408 write_csr(CSR_PMPADDR3, 0);
409 write_csr(CSR_PMPADDR4, 0);
410 write_csr(CSR_PMPADDR5, 0);
411 write_csr(CSR_PMPADDR6, 0);
412 write_csr(CSR_PMPADDR7, 0);
413 write_csr(CSR_PMPADDR8, 0);
414 write_csr(CSR_PMPADDR9, 0);
415 write_csr(CSR_PMPADDR10, 0);
416 write_csr(CSR_PMPADDR11, 0);
417 write_csr(CSR_PMPADDR12, 0);
418 write_csr(CSR_PMPADDR13, 0);
419 write_csr(CSR_PMPADDR14, 0);
420 write_csr(CSR_PMPADDR15, 0);
421 #if (!defined(PMP_SUPPORT_PMA)) || (defined(PMP_SUPPORT_PMA) && (PMP_SUPPORT_PMA == 1))
422 write_csr(CSR_PMACFG0, 0);
423 write_csr(CSR_PMACFG1, 0);
424 write_csr(CSR_PMACFG2, 0);
425 write_csr(CSR_PMACFG3, 0);
426 write_csr(CSR_PMAADDR0, 0);
427 write_csr(CSR_PMAADDR1, 0);
428 write_csr(CSR_PMAADDR2, 0);
429 write_csr(CSR_PMAADDR3, 0);
430 write_csr(CSR_PMAADDR4, 0);
431 write_csr(CSR_PMAADDR5, 0);
432 write_csr(CSR_PMAADDR6, 0);
433 write_csr(CSR_PMAADDR7, 0);
434 write_csr(CSR_PMAADDR8, 0);
435 write_csr(CSR_PMAADDR9, 0);
436 write_csr(CSR_PMAADDR10, 0);
437 write_csr(CSR_PMAADDR11, 0);
438 write_csr(CSR_PMAADDR12, 0);
439 write_csr(CSR_PMAADDR13, 0);
440 write_csr(CSR_PMAADDR14, 0);
441 write_csr(CSR_PMAADDR15, 0);
442 #endif
443 fencei();
444 write_csr(CSR_MCACHE_CTL, mcache_ctl);
445 fencei();
446 }
447