• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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