10 #include "sw/device/lib/runtime/pmp.h"
12 #include "sw/device/lib/testing/pinmux_testutils.h"
13 #include "sw/device/lib/testing/test_framework/check.h"
14 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
15 #include "sw/device/lib/testing/test_framework/status.h"
16 #include "sw/device/silicon_creator/lib/dbg_print.h"
17 #include "sw/device/silicon_creator/lib/epmp_defs.h"
21 OTTF_DEFINE_TEST_CONFIG();
28 extern const char __rodata_end[];
30 extern const char i_am_become_user[];
31 extern const char kIAmBecomeUserEnd[];
33 extern const char kExpUInstrAccFaultRet[];
35 extern const char kExpMInstrAccFaultRet[];
37 extern void (*finish_test)(void);
42 static dif_uart_t uart0;
43 static dif_pinmux_t pinmux;
60 enum { kNumLocations = 4 };
61 volatile uint32_t test_locations[kNumLocations] = {
70 static inline bool was_in_machine_mode(
void) {
74 const uint32_t kMppOffset = 11;
75 return ((mstatus >> kMppOffset) & 0x3) == 0x3;
78 void ottf_exception_handler(uint32_t *exc_info) {
81 bool m_mode_exception = was_in_machine_mode();
89 uint32_t mpec = *mepc_stack_addr;
92 case kIbexExcLoadAccessFault:
93 if (m_mode_exception) {
94 CHECK(mtval == (uint32_t)(test_locations + 0),
95 "Unexpected M Mode Load Access Fault:"
96 " mpec = 0x%08x, mtval = 0x%08x",
99 CHECK(mtval == (uint32_t)(test_locations + 1) ||
100 mtval == (uint32_t)(test_locations + 3),
101 "Unexpected U Mode Load Access Fault:"
102 " mpec = 0x%08x, mtval = 0x%08x",
106 case kIbexExcStoreAccessFault:
107 if (m_mode_exception) {
108 CHECK(mtval == (uint32_t)(test_locations + 0) ||
109 mtval == (uint32_t)(test_locations + 3),
110 "Unexpected M Mode Store Access Fault:"
111 " mpec = 0x%08x, mtval = 0x%08x",
114 CHECK(mtval == (uint32_t)(test_locations + 0) ||
115 mtval == (uint32_t)(test_locations + 1) ||
116 mtval == (uint32_t)(test_locations + 2) ||
117 mtval == (uint32_t)(test_locations + 3),
118 "Unexpected U Mode Store Access Fault:"
119 " mpec = 0x%08x, mtval = 0x%08x",
123 case kIbexExcInstrAccessFault:
124 CHECK(mtval == (uint32_t)(test_locations + 0) ||
125 mtval == (uint32_t)(test_locations + 1) ||
126 mtval == (uint32_t)(test_locations + 2),
127 "Unexpected Instruction Access Fault:"
128 " mpec = 0x%08x, mtval = 0x%08x",
130 *mepc_stack_addr = m_mode_exception ? (uintptr_t)kExpMInstrAccFaultRet
131 : (uintptr_t)kExpUInstrAccFaultRet;
133 case kIbexExcUserECall:
134 test_status_set(kTestStatusPassed);
139 "Unexpected Exception:"
140 " mcause = 0x%x, mpec 0x%x, mtval = 0x%x",
141 mcause, mpec, mtval);
152 inline uint32_t tor_address(uint32_t addr) {
return addr >> 2; }
160 inline uint32_t region_pmpcfg(uint32_t region) {
161 switch (region / 4) {
163 return CSR_REG_PMPCFG0;
165 return CSR_REG_PMPCFG1;
167 return CSR_REG_PMPCFG2;
169 return CSR_REG_PMPCFG3;
181 inline uint32_t region_offset(uint32_t region) {
return region % 4 * 8; }
193 static void pmp_setup_machine_area(
void) {
199 const uint32_t kRodataEnd = (uint32_t)__rodata_end;
203 CSR_WRITE(CSR_REG_PMPADDR8, tor_address(kRodataEnd));
204 CSR_WRITE(CSR_REG_PMPADDR9, tor_address(kSramEnd));
206 const uint32_t pmp9cfg = EPMP_CFG_A_TOR | EPMP_CFG_LRW;
207 CSR_SET_BITS(region_pmpcfg(9), pmp9cfg << region_offset(1));
210 CSR_CLEAR_BITS(region_pmpcfg(11), EPMP_CFG_X << region_offset(11));
213 CHECK(!((csr >> region_offset(11)) & EPMP_CFG_X),
214 "Couldn't remove execute access to PMP region 11.");
217 CSR_CLEAR_BITS(region_pmpcfg(13), EPMP_CFG_W << region_offset(13));
218 CSR_CLEAR_BITS(region_pmpcfg(15), EPMP_CFG_W << region_offset(15));
220 CHECK(!((csr >> region_offset(13)) & EPMP_CFG_W),
221 "Couldn't remove write access from PMP region 15.");
222 CHECK(!((csr >> region_offset(15)) & EPMP_CFG_W),
223 "Couldn't remove write access from PMP region 15.");
231 static void pmp_setup_user_area(
void) {
232 const uintptr_t kStart = (uintptr_t)i_am_become_user;
233 const uintptr_t kEnd = (uintptr_t)kIAmBecomeUserEnd;
235 CSR_WRITE(CSR_REG_PMPADDR0, tor_address(kStart));
236 CSR_WRITE(CSR_REG_PMPADDR1, tor_address(kEnd));
238 const uint32_t pmp1cfg = (EPMP_CFG_A_TOR | EPMP_CFG_LRWX) ^ EPMP_CFG_R;
239 CSR_SET_BITS(region_pmpcfg(1), pmp1cfg << region_offset(1));
248 static void pmp_setup_test_locations(
void) {
249 CSR_WRITE(CSR_REG_PMPADDR3, tor_address((uintptr_t)(test_locations + 0)));
250 CSR_WRITE(CSR_REG_PMPADDR4, tor_address((uintptr_t)(test_locations + 1)));
251 CSR_WRITE(CSR_REG_PMPADDR5, tor_address((uintptr_t)(test_locations + 2)));
252 CSR_WRITE(CSR_REG_PMPADDR6, tor_address((uintptr_t)(test_locations + 3)));
253 CSR_WRITE(CSR_REG_PMPADDR7, tor_address((uintptr_t)(test_locations + 4)));
255 uint32_t cfg = EPMP_CFG_A_TOR | EPMP_CFG_R;
256 CSR_SET_BITS(region_pmpcfg(4), cfg << region_offset(4));
257 cfg = EPMP_CFG_A_TOR | EPMP_CFG_LRW;
258 CSR_SET_BITS(region_pmpcfg(5), cfg << region_offset(5));
259 cfg = EPMP_CFG_A_TOR | EPMP_CFG_W;
260 CSR_SET_BITS(region_pmpcfg(6), cfg << region_offset(6));
261 cfg = EPMP_CFG_A_TOR | EPMP_CFG_L | EPMP_CFG_X | EPMP_CFG_W;
262 CSR_SET_BITS(region_pmpcfg(7), cfg << region_offset(7));
268 static void setup_uart(
void) {
270 CHECK_DIF_OK(dif_pinmux_init(
272 CHECK_DIF_OK(dif_uart_init(
276 pinmux_testutils_init(&pinmux);
277 CHECK(
kUartBaudrate <= UINT32_MAX,
"kUartBaudrate must fit in uint32_t");
279 "kClockFreqPeripheralHz must fit in uint32_t");
302 pmp_setup_machine_area();
304 LOG_INFO(
"Enable Machine Mode Lockdown");
307 pmp_setup_user_area();
308 pmp_setup_test_locations();
315 for (
size_t loc = 0; loc < kNumLocations; ++loc) {
316 test_locations[loc] = 42;
317 load = test_locations[loc];
318 ((void (*)(void))(test_locations + loc))();
329 "la t0, i_am_become_user\n"