提交 926cbae1 编写于 作者: W William Wang

tests,pmp: fix riscv64-xs pmp test

上级 51e329c7
#include <riscv.h>
#include <nemu.h>
// #include <printf.h>
#include <printf.h>
extern void __am_timervec(void);
static void init_machine_exception() {
......@@ -34,11 +34,15 @@ void __am_init_cte64() {
init_pmp();
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
// protect 0x90000000 + 0x10000 for test purpose
enable_pmp(1, 0x90000000, 0x10000, 0, 0);
printf("enable_pmp\n");
enable_pmp(1, 0x90000000, 0x10000, 0, 0); // !rw
// printf("pmp NA inited\n");
// protect 0xb00000000 + 0x100
enable_pmp_TOR(4, 0xb0000000, 0x100, 0, 0);
enable_pmp_TOR(3, 0xb0000000, 0x1000, 0, 0); // !rw
//printf("pmp TOR inited\n");
enable_pmp_TOR(5, 0xb0004000, 0x1000, 0, PMP_R); // r,!w
enable_pmp_TOR(7, 0xb0008000, 0x1000, 0, PMP_W); // !r, w
enable_pmp_TOR(9, 0xb0010000, 0x1000, 0, 0); // !r, w
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
// protect 0x210000000 + 0x10000 for test purpose
enable_pmp(1, 0x2010000000, 0x10000, 0, 0);
......
......@@ -208,7 +208,8 @@ void init_pmp() {
}
// set PMP to access all memory in S-mode
// asm volatile("csrw pmpaddr8, %0" : : "r"(-1));
asm volatile("csrw pmpcfg2, %0" : : "r"(31));
// the last pmp pair is used to enable all access (in current case is pmp15)
asm volatile("csrw pmpcfg2, %0" : : "r"((long)31<<(8*7)));
asm volatile("sfence.vma");
}
......
......@@ -7,50 +7,191 @@
* You may find related initialzation code in __am_init_cte64()
*/
#define PMP_1
#define EXCEPTION_LOAD_ACCESS_FAULT 5
#define EXCEPTION_STORE_ACCESS_FAULT 7
uint64_t access_fault_to_be_reported = 0;
inline int inst_is_compressed(uint64_t addr){
uint8_t byte = *(uint8_t*)addr;
return (byte & 0x3) != 0x3;
}
uint64_t store_access_fault_to_be_reported = 0;
uint64_t store_access_fault_reported = 0;
uint64_t load_access_fault_to_be_reported = 0;
uint64_t load_access_fault_reported = 0;
_Context* store_access_fault_handler(_Event* ev, _Context *c) {
printf("store access fault triggered\n");
if (access_fault_to_be_reported) {
_halt(0);
volatile int result_blackhole = 0;
void reset_result_flags() {
store_access_fault_to_be_reported = 0;
store_access_fault_reported = 0;
load_access_fault_to_be_reported = 0;
load_access_fault_reported = 0;
}
void result_check() {
assert(!(store_access_fault_to_be_reported && load_access_fault_to_be_reported));
if (store_access_fault_to_be_reported) {
if (!store_access_fault_reported || load_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported);
_halt(1);
}
} else if (load_access_fault_to_be_reported) {
if (!load_access_fault_reported || store_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported);
_halt(1);
}
} else {
_halt(1); // something went wrong
if (load_access_fault_reported || store_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported);
_halt(1);
}
}
// result check passed, reset flags
store_access_fault_to_be_reported = 0;
store_access_fault_reported = 0;
load_access_fault_to_be_reported = 0;
load_access_fault_reported = 0;
}
_Context* store_access_fault_handler(_Event* ev, _Context *c) {
printf("store access fault triggered, sepc %lx\n", c->sepc);
store_access_fault_reported = 1;
// skip the inst that triggered the exception
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
// printf("goto %x\n", c->sepc);
return c;
}
_Context* load_access_fault_handler(_Event* ev, _Context *c) {
printf("load access fault triggered, sepc %lx\n", c->sepc);
load_access_fault_reported = 1;
// skip the inst that triggered the exception
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
// printf("goto %x\n", c->sepc);
return c;
}
void pmp_test() {
irq_handler_reg(EXCEPTION_STORE_ACCESS_FAULT, &store_access_fault_handler);
irq_handler_reg(EXCEPTION_LOAD_ACCESS_FAULT, &load_access_fault_handler);
printf("start pmp test\n");
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
#ifdef PMP_1
access_fault_to_be_reported = 1;
// Case: store to address protected by pmp
store_access_fault_to_be_reported = 1;
volatile int *a = (int *)(0x90000040UL);
*a = 1; // should trigger a fault
#endif
#ifdef PMP_2
access_fault_to_be_reported = 0;
result_check();
printf("line %d passed\n", __LINE__);
// Case: store to normal cacheable address
int *b = (int *)(0xa0000000UL);
*b = 1; // should not trigger a fault
#endif
#ifdef PMP_3
access_fault_to_be_reported = 1;
int *c = (int *)(0xb00000040UL);
result_check();
printf("line %d passed\n", __LINE__);
// Case: store to address protected by pmp tor
store_access_fault_to_be_reported = 1;
int *c = (int *)(0xb0000040UL);
*c = 1; // should trigger a fault
#endif
result_check();
printf("line %d passed\n", __LINE__);
// Case: load from address protected by pmp
load_access_fault_to_be_reported = 1;
volatile int *d = (int *)(0x90000040UL);
result_blackhole = (*d); // should trigger a fault
result_check();
printf("line %d passed\n", __LINE__);
// Case: load from address protected by pmp tor
load_access_fault_to_be_reported = 1;
volatile int *e = (int *)(0xb0000040UL);
result_blackhole = (*e); // should trigger a fault
result_check();
printf("line %d passed\n", __LINE__);
// Case: store to address protected by pmp (use pmpcfg2)
store_access_fault_to_be_reported = 1;
int *f = (int *)(0xb0010000UL);
*f = 1; // should trigger a fault
result_check();
printf("line %d passed\n", __LINE__);
// Case: lr from address protected by pmp
load_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb0000040;"
"lr.d s5, (s4);"
:
:
:"s4","s5","s6"
);
result_check();
printf("line %d passed\n", __LINE__);
// Case: sc to address protected by pmp
store_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb0000040;"
"sc.d s5, s5, (s4);"
:
:
:"s4","s5","s6"
);
result_check();
printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp
store_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb0000040;"
"amoadd.d s5, s6, (s4);"
:
:
:"s4","s5","s6"
);
result_check();
printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp (w,!r)
store_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb0008000;"
"amoadd.d s5, s6, (s4);"
:
:
:"s4","s5","s6"
);
result_check();
printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp (!w,r)
store_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb0004000;"
"amoadd.d s5, s6, (s4);"
:
:
:"s4","s5","s6"
);
result_check();
printf("line %d passed\n", __LINE__);
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
access_fault_to_be_reported = 0;
// TODO: update pmp test for southlake
store_access_fault_to_be_reported = 0;
int *b = (int *)(0x2030000000UL);
*b = 1; // should not trigger a fault
access_fault_to_be_reported = 1;
result_check();
store_access_fault_to_be_reported = 1;
volatile int *a = (int *)(0x2010000040UL);
*a = 1; // should trigger a fault
printf("Store access fault not triggered\n");
_halt(1);
result_check();
#else
// invalid arch
printf("invalid arch\n");
......
......@@ -21,7 +21,7 @@ uint64_t page_fault_to_be_reported = 0;
inline int inst_is_compressed(uint64_t addr){
uint8_t byte = *(uint8_t*)addr;
return (byte | 0x3) != 0x3;
return (byte & 0x3) != 0x3;
}
_Context* store_page_fault_handler(_Event* ev, _Context *c) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册