5 #include "sw/device/silicon_creator/lib/drivers/epmp.h"
10 #include "sw/device/silicon_creator/lib/epmp_state.h"
14 #define EPMP_SET(cfg_reg, addr_reg, mask, cfg, addr) \
15 CSR_CLEAR_BITS(CSR_REG_PMPCFG##cfg_reg, mask); \
16 CSR_WRITE(CSR_REG_PMPADDR##addr_reg, pmpaddr); \
17 CSR_SET_BITS(CSR_REG_PMPCFG##cfg_reg, cfg);
19 void epmp_set(uint8_t entry, uint32_t pmpcfg, uint32_t pmpaddr) {
20 uint32_t shift = 8 * (entry % 4);
21 uint32_t mask = 0xFFu << shift;
22 uint32_t cfg = (pmpcfg & 0xFFu) << shift;
23 HARDENED_CHECK_LT(entry, 16);
26 case 0: EPMP_SET(0, 0, mask, cfg, pmpaddr);
break;
27 case 1: EPMP_SET(0, 1, mask, cfg, pmpaddr);
break;
28 case 2: EPMP_SET(0, 2, mask, cfg, pmpaddr);
break;
29 case 3: EPMP_SET(0, 3, mask, cfg, pmpaddr);
break;
30 case 4: EPMP_SET(1, 4, mask, cfg, pmpaddr);
break;
31 case 5: EPMP_SET(1, 5, mask, cfg, pmpaddr);
break;
32 case 6: EPMP_SET(1, 6, mask, cfg, pmpaddr);
break;
33 case 7: EPMP_SET(1, 7, mask, cfg, pmpaddr);
break;
34 case 8: EPMP_SET(2, 8, mask, cfg, pmpaddr);
break;
35 case 9: EPMP_SET(2, 9, mask, cfg, pmpaddr);
break;
36 case 10: EPMP_SET(2, 10, mask, cfg, pmpaddr);
break;
37 case 11: EPMP_SET(2, 11, mask, cfg, pmpaddr);
break;
38 case 12: EPMP_SET(3, 12, mask, cfg, pmpaddr);
break;
39 case 13: EPMP_SET(3, 13, mask, cfg, pmpaddr);
break;
40 case 14: EPMP_SET(3, 14, mask, cfg, pmpaddr);
break;
41 case 15: EPMP_SET(3, 15, mask, cfg, pmpaddr);
break;
47 uint32_t cfgent = entry / 4;
52 void epmp_clear(uint8_t entry) { epmp_set(entry, kEpmpModeOff, 0); }
54 void epmp_clear_lock_bits(
void) {
56 ((uint32_t)EPMP_CFG_L << 0 * 8) | ((uint32_t)EPMP_CFG_L << 1 * 8) |
57 ((uint32_t)EPMP_CFG_L << 2 * 8) | ((uint32_t)EPMP_CFG_L << 3 * 8);
62 for (
int cfgent = 0; cfgent < 4; ++cfgent) {
68 const uint32_t length = region.end - region.start;
70 HARDENED_CHECK_GE(length, 4);
75 return (region.start >> 2) | ((length - 1) >> 3);
79 HARDENED_CHECK_NE(pmpaddr, UINT32_MAX);
81 pmpaddr = (pmpaddr & ~(size - 1)) << 2;
83 return (
epmp_region_t){.start = pmpaddr, .end = pmpaddr + size};
86 void epmp_set_napot(uint8_t entry,
epmp_region_t region, epmp_perm_t perm) {
87 uint32_t addr = epmp_encode_napot(region);
89 region.end - region.start == 4 ? kEpmpModeNa4 : kEpmpModeNapot;
90 epmp_set(entry, (uint32_t)mode | (uint32_t)perm, addr);
93 void epmp_set_tor(uint8_t entry,
epmp_region_t region, epmp_perm_t perm) {
94 uint32_t start = region.start >> 2;
95 uint32_t end = ((region.end + 3u) & ~3u) >> 2;
96 epmp_set(entry, kEpmpModeOff, start);
97 epmp_set(entry + 1, (uint32_t)kEpmpModeTor | (uint32_t)perm, end);
100 void epmp_clear_rlb(
void) {
101 const uint32_t kMask = EPMP_MSECCFG_RLB;