5 #include "sw/device/silicon_creator/rom/rom_epmp.h"
21 #include "sw/device/lib/testing/pinmux_testutils.h"
22 #include "sw/device/lib/testing/test_framework/status.h"
24 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
25 #include "sw/device/silicon_creator/lib/drivers/uart.h"
26 #include "sw/device/silicon_creator/lib/epmp_test_unlock.h"
27 #include "sw/device/silicon_creator/rom/rom_epmp.h"
29 #include "flash_ctrl_regs.h"
47 static uint32_t get_mcause(
void) {
58 static uint32_t get_mepc(
void) {
72 static void set_mepc(uint32_t pc) {
CSR_WRITE(CSR_REG_MEPC, pc); }
95 volatile uintptr_t exception_pc = 0;
110 void rom_exception_handler(
void) __attribute__((interrupt));
111 void rom_exception_handler(
void) {
112 uint32_t mcause = get_mcause();
113 if (mcause == kIbexExcInstrAccessFault ||
114 mcause == kIbexExcIllegalInstrFault) {
116 exception_pc = get_mepc();
119 uintptr_t ret = (uintptr_t)__builtin_return_address(0);
120 set_mepc((uint32_t)ret);
145 static bool execute(
const void *pc,
ibex_exc_t expect) {
147 exception_received = kIbexExcMax;
165 ((void (*)(void))pc)();
171 if (exception_received != kIbexExcMax && exception_pc != (uintptr_t)pc) {
174 return exception_received == expect;
187 static const uint32_t kUnimpInstruction = UINT32_MAX;
192 static const uint32_t illegal_ins_ro[] = {
199 static uint32_t illegal_ins_rw[] = {
212 static bool is_in_address_space(
const void *ptr, uintptr_t start,
214 return (uintptr_t)ptr >= start && (uintptr_t)ptr < (start + size);
220 static bool passed =
false;
227 #define CHECK(condition) \
228 if (!(condition)) { \
229 LOG_ERROR("CHECK-fail: " #condition); \
236 static void test_noexec_rodata(
void) {
239 CHECK(execute(illegal_ins_ro, kIbexExcInstrAccessFault));
245 static void test_noexec_rwdata(
void) {
246 dif_sram_ctrl_t sram_ctrl;
247 CHECK(dif_sram_ctrl_init(
254 CHECK(execute(illegal_ins_rw, kIbexExcInstrAccessFault));
260 static void test_noexec_eflash(
void) {
266 CHECK(execute(&eflash[0], kIbexExcInstrAccessFault));
267 CHECK(execute(&eflash[eflash_len - 1], kIbexExcInstrAccessFault));
271 size_t step = eflash_len / 999;
272 for (
size_t i = step; i < eflash_len; i += step) {
273 if (!execute(&eflash[i], kIbexExcInstrAccessFault)) {
274 LOG_ERROR(
"eflash execution not blocked @ %p", &eflash[i]);
285 static void test_noexec_mmio(
void) {
288 dif_sram_ctrl_t ret_ram_ctrl;
291 &ret_ram_ctrl) ==
kDifOk);
296 ret_ram[0] = kUnimpInstruction;
297 CHECK(execute(&ret_ram[0], kIbexExcInstrAccessFault));
298 ret_ram[ret_ram_len - 1] = kUnimpInstruction;
299 CHECK(execute(&ret_ram[ret_ram_len - 1], kIbexExcInstrAccessFault));
312 static void test_unlock_exec_eflash(
void) {
318 uint32_t *image = &eflash[eflash_len / 5];
319 size_t image_len = eflash_len / 7;
321 .end = (uintptr_t)&image[image_len]};
325 rom_epmp_unlock_rom_ext_rx(region);
326 CHECK(epmp_state_check() == kErrorOk);
333 CHECK(image[0] == kUnimpInstruction);
334 CHECK(execute(&image[0], kIbexExcIllegalInstrFault));
335 CHECK(image[image_len - 1] == kUnimpInstruction);
336 CHECK(execute(&image[image_len - 1], kIbexExcIllegalInstrFault));
339 CHECK(execute(&image[-1], kIbexExcInstrAccessFault));
340 CHECK(execute(&image[image_len], kIbexExcInstrAccessFault));
343 void rom_main(
void) {
347 exception_received = kIbexExcMax;
348 illegal_ins_rw[0] = kUnimpInstruction;
354 rom_epmp_config_debug_rom(kLcStateProd);
360 pinmux_testutils_init(&pinmux);
364 flash_ctrl_exec_set(FLASH_CTRL_PARAM_EXEC_EN);
375 LOG_INFO(
"Starting ROM ePMP functional test.");
379 rom_epmp_state_init(kLcStateProd);
380 CHECK(epmp_state_check() == kErrorOk);
383 test_noexec_rodata();
384 test_noexec_rwdata();
385 test_noexec_eflash();
390 test_unlock_exec_eflash();
395 CHECK(epmp_unlock_test_status());
401 test_status_set(kTestStatusInTest);
402 test_status_set(passed ? kTestStatusPassed : kTestStatusFailed);