提交 f5e7537a 编写于 作者: W William Wang

tests: add riscv64 hugepage-pmp-atom mixed test

上级 926cbae1
...@@ -84,6 +84,9 @@ void _unprotect(_AddressSpace *as); ...@@ -84,6 +84,9 @@ void _unprotect(_AddressSpace *as);
void _map(_AddressSpace *as, void *va, void *pa, int prot); void _map(_AddressSpace *as, void *va, void *pa, int prot);
_Context *_ucontext(_AddressSpace *as, _Area kstack, void *entry); _Context *_ucontext(_AddressSpace *as, _Area kstack, void *entry);
// hugepage map for xiangshan testing
void _map_rv_hugepage(_AddressSpace *as, void *va, void *pa, int prot, int pagetable_level);
// ================= Multi-Processor Extension (MPE) ================= // ================= Multi-Processor Extension (MPE) =================
int _mpe_init(void (*entry)()); int _mpe_init(void (*entry)());
......
...@@ -61,6 +61,7 @@ static inline void *new_page() { ...@@ -61,6 +61,7 @@ static inline void *new_page() {
memset(p, 0, PGSIZE); memset(p, 0, PGSIZE);
return p; return p;
} }
/* /*
* Virtual Memory initialize * Virtual Memory initialize
* pgalloc_f: pointer of page table memory allocater, must return page-aligned address * pgalloc_f: pointer of page table memory allocater, must return page-aligned address
...@@ -101,12 +102,14 @@ void _protect(_AddressSpace *as) { ...@@ -101,12 +102,14 @@ void _protect(_AddressSpace *as) {
void _unprotect(_AddressSpace *as) { void _unprotect(_AddressSpace *as) {
} }
/* /*
* get current satp * get current satp
*/ */
void __am_get_cur_as(_Context *c) { void __am_get_cur_as(_Context *c) {
c->pdir = (vme_enable ? (void *)get_satp() : NULL); c->pdir = (vme_enable ? (void *)get_satp() : NULL);
} }
/* /*
* switch page table to the given context * switch page table to the given context
*/ */
...@@ -115,6 +118,7 @@ void __am_switch(_Context *c) { ...@@ -115,6 +118,7 @@ void __am_switch(_Context *c) {
set_satp(c->pdir); set_satp(c->pdir);
} }
} }
/* /*
* map va to pa with prot permission with page table root as * map va to pa with prot permission with page table root as
* Note that RISC-V allow hardware to fault when A and D bit is not set * Note that RISC-V allow hardware to fault when A and D bit is not set
...@@ -140,6 +144,45 @@ void _map(_AddressSpace *as, void *va, void *pa, int prot) { ...@@ -140,6 +144,45 @@ void _map(_AddressSpace *as, void *va, void *pa, int prot) {
} }
} }
/*
* map va to pa with prot permission with page table root as
* pagetable_level indicates page table level to be used
* 0: basic 4KiB page
* 1: 2MiB megapage
* 2: 1GiB gigapage
* Note that RISC-V allow hardware to fault when A and D bit is not set
*/
void _map_rv_hugepage(_AddressSpace *as, void *va, void *pa, int prot, int pagetable_level) {
int hugepage_size;
switch (pagetable_level) {
case 0: hugepage_size = PGSIZE; break; // 4KiB
case 1: hugepage_size = PGSIZE * 512; break; // 2MiB
case 2: hugepage_size = PGSIZE * 512 * 512; break; // 1GiB
default: assert(0);
}
assert((uintptr_t)va % hugepage_size == 0);
// printf("pa %lx sz %lx\n", pa, hugepage_size);
assert((uintptr_t)pa % hugepage_size == 0);
PTE *pg_base = as->ptr;
PTE *pte;
int level;
for (level = PTW_CONFIG.ptw_level - 1; ; level --) {
pte = &pg_base[VPNi(PTW_CONFIG, (uintptr_t)va, level)];
pg_base = (PTE *)PTE_ADDR(*pte);
if (level == pagetable_level) break;
if (!(*pte & PTE_V)) {
pg_base = new_page();
*pte = PTE_V | (PN(pg_base) << 10);
}
}
int hugepage_pn_shift = pagetable_level * 9;
if (!(*pte & PTE_V)) {
*pte = PTE_V | prot | (PN(pa) >> hugepage_pn_shift << hugepage_pn_shift << 10);
}
printf("map huge page level %d, pte value %lx\n", pagetable_level, *pte);
}
_Context *_ucontext(_AddressSpace *as, _Area kstack, void *entry) { _Context *_ucontext(_AddressSpace *as, _Area kstack, void *entry) {
_Context *c = (_Context*)kstack.end - 1; _Context *c = (_Context*)kstack.end - 1;
......
...@@ -33,6 +33,7 @@ int main(const char *args) { ...@@ -33,6 +33,7 @@ int main(const char *args) {
CASE('p', vm_test, CTE(vm_handler), VME(simple_pgalloc, simple_pgfree)); CASE('p', vm_test, CTE(vm_handler), VME(simple_pgalloc, simple_pgfree));
CASE('c', pmp_test, CTE(simple_trap)); CASE('c', pmp_test, CTE(simple_trap));
CASE('s', sv39_test, IOE, CTE(simple_trap)); CASE('s', sv39_test, IOE, CTE(simple_trap));
CASE('f', sv39_hp_atom_test, IOE, CTE(simple_trap));
CASE('b', cache_test); CASE('b', cache_test);
case 'H': case 'H':
default: default:
......
...@@ -15,60 +15,60 @@ inline int inst_is_compressed(uint64_t addr){ ...@@ -15,60 +15,60 @@ inline int inst_is_compressed(uint64_t addr){
return (byte & 0x3) != 0x3; return (byte & 0x3) != 0x3;
} }
uint64_t store_access_fault_to_be_reported = 0; volatile uint64_t pmp_store_access_fault_to_be_reported = 0;
uint64_t store_access_fault_reported = 0; volatile uint64_t pmp_store_access_fault_reported = 0;
uint64_t load_access_fault_to_be_reported = 0; volatile uint64_t pmp_load_access_fault_to_be_reported = 0;
uint64_t load_access_fault_reported = 0; volatile uint64_t pmp_load_access_fault_reported = 0;
volatile int result_blackhole = 0; volatile int result_blackhole = 0;
void reset_result_flags() { void reset_result_flags() {
store_access_fault_to_be_reported = 0; pmp_store_access_fault_to_be_reported = 0;
store_access_fault_reported = 0; pmp_store_access_fault_reported = 0;
load_access_fault_to_be_reported = 0; pmp_load_access_fault_to_be_reported = 0;
load_access_fault_reported = 0; pmp_load_access_fault_reported = 0;
} }
void result_check() { void result_check() {
assert(!(store_access_fault_to_be_reported && load_access_fault_to_be_reported)); assert(!(pmp_store_access_fault_to_be_reported && pmp_load_access_fault_to_be_reported));
if (store_access_fault_to_be_reported) { if (pmp_store_access_fault_to_be_reported) {
if (!store_access_fault_reported || load_access_fault_reported) { if (!pmp_store_access_fault_reported || pmp_load_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n", printf("pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported); pmp_store_access_fault_reported, pmp_load_access_fault_reported);
_halt(1); _halt(1);
} }
} else if (load_access_fault_to_be_reported) { } else if (pmp_load_access_fault_to_be_reported) {
if (!load_access_fault_reported || store_access_fault_reported) { if (!pmp_load_access_fault_reported || pmp_store_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n", printf("pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported); pmp_store_access_fault_reported, pmp_load_access_fault_reported);
_halt(1); _halt(1);
} }
} else { } else {
if (load_access_fault_reported || store_access_fault_reported) { if (pmp_load_access_fault_reported || pmp_store_access_fault_reported) {
printf("store_access_fault_reported %x, load_access_fault_reported %x\n", printf("pmp_store_access_fault_reported %x, pmp_load_access_fault_reported %x\n",
store_access_fault_reported, load_access_fault_reported); pmp_store_access_fault_reported, pmp_load_access_fault_reported);
_halt(1); _halt(1);
} }
} }
// result check passed, reset flags // result check passed, reset flags
store_access_fault_to_be_reported = 0; pmp_store_access_fault_to_be_reported = 0;
store_access_fault_reported = 0; pmp_store_access_fault_reported = 0;
load_access_fault_to_be_reported = 0; pmp_load_access_fault_to_be_reported = 0;
load_access_fault_reported = 0; pmp_load_access_fault_reported = 0;
} }
_Context* store_access_fault_handler(_Event* ev, _Context *c) { _Context* pmp_store_access_fault_handler(_Event* ev, _Context *c) {
printf("store access fault triggered, sepc %lx\n", c->sepc); printf("store access fault triggered, sepc %lx\n", c->sepc);
store_access_fault_reported = 1; pmp_store_access_fault_reported = 1;
// skip the inst that triggered the exception // skip the inst that triggered the exception
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4; c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
// printf("goto %x\n", c->sepc); // printf("goto %x\n", c->sepc);
return c; return c;
} }
_Context* load_access_fault_handler(_Event* ev, _Context *c) { _Context* pmp_load_access_fault_handler(_Event* ev, _Context *c) {
printf("load access fault triggered, sepc %lx\n", c->sepc); printf("load access fault triggered, sepc %lx\n", c->sepc);
load_access_fault_reported = 1; pmp_load_access_fault_reported = 1;
// skip the inst that triggered the exception // skip the inst that triggered the exception
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4; c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
// printf("goto %x\n", c->sepc); // printf("goto %x\n", c->sepc);
...@@ -76,12 +76,12 @@ _Context* load_access_fault_handler(_Event* ev, _Context *c) { ...@@ -76,12 +76,12 @@ _Context* load_access_fault_handler(_Event* ev, _Context *c) {
} }
void pmp_test() { void pmp_test() {
irq_handler_reg(EXCEPTION_STORE_ACCESS_FAULT, &store_access_fault_handler); irq_handler_reg(EXCEPTION_STORE_ACCESS_FAULT, &pmp_store_access_fault_handler);
irq_handler_reg(EXCEPTION_LOAD_ACCESS_FAULT, &load_access_fault_handler); irq_handler_reg(EXCEPTION_LOAD_ACCESS_FAULT, &pmp_load_access_fault_handler);
printf("start pmp test\n"); printf("start pmp test\n");
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS) #if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
// Case: store to address protected by pmp // Case: store to address protected by pmp
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
volatile int *a = (int *)(0x90000040UL); volatile int *a = (int *)(0x90000040UL);
*a = 1; // should trigger a fault *a = 1; // should trigger a fault
result_check(); result_check();
...@@ -94,35 +94,35 @@ void pmp_test() { ...@@ -94,35 +94,35 @@ void pmp_test() {
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: store to address protected by pmp tor // Case: store to address protected by pmp tor
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
int *c = (int *)(0xb0000040UL); int *c = (int *)(0xb0000040UL);
*c = 1; // should trigger a fault *c = 1; // should trigger a fault
result_check(); result_check();
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: load from address protected by pmp // Case: load from address protected by pmp
load_access_fault_to_be_reported = 1; pmp_load_access_fault_to_be_reported = 1;
volatile int *d = (int *)(0x90000040UL); volatile int *d = (int *)(0x90000040UL);
result_blackhole = (*d); // should trigger a fault result_blackhole = (*d); // should trigger a fault
result_check(); result_check();
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: load from address protected by pmp tor // Case: load from address protected by pmp tor
load_access_fault_to_be_reported = 1; pmp_load_access_fault_to_be_reported = 1;
volatile int *e = (int *)(0xb0000040UL); volatile int *e = (int *)(0xb0000040UL);
result_blackhole = (*e); // should trigger a fault result_blackhole = (*e); // should trigger a fault
result_check(); result_check();
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: store to address protected by pmp (use pmpcfg2) // Case: store to address protected by pmp (use pmpcfg2)
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
int *f = (int *)(0xb0010000UL); int *f = (int *)(0xb0010000UL);
*f = 1; // should trigger a fault *f = 1; // should trigger a fault
result_check(); result_check();
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: lr from address protected by pmp // Case: lr from address protected by pmp
load_access_fault_to_be_reported = 1; pmp_load_access_fault_to_be_reported = 1;
asm volatile( asm volatile(
"li s4, 0xb0000040;" "li s4, 0xb0000040;"
"lr.d s5, (s4);" "lr.d s5, (s4);"
...@@ -134,7 +134,7 @@ void pmp_test() { ...@@ -134,7 +134,7 @@ void pmp_test() {
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: sc to address protected by pmp // Case: sc to address protected by pmp
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
asm volatile( asm volatile(
"li s4, 0xb0000040;" "li s4, 0xb0000040;"
"sc.d s5, s5, (s4);" "sc.d s5, s5, (s4);"
...@@ -146,7 +146,7 @@ void pmp_test() { ...@@ -146,7 +146,7 @@ void pmp_test() {
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp // Case: amo to address protected by pmp
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
asm volatile( asm volatile(
"li s4, 0xb0000040;" "li s4, 0xb0000040;"
"amoadd.d s5, s6, (s4);" "amoadd.d s5, s6, (s4);"
...@@ -158,7 +158,7 @@ void pmp_test() { ...@@ -158,7 +158,7 @@ void pmp_test() {
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp (w,!r) // Case: amo to address protected by pmp (w,!r)
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
asm volatile( asm volatile(
"li s4, 0xb0008000;" "li s4, 0xb0008000;"
"amoadd.d s5, s6, (s4);" "amoadd.d s5, s6, (s4);"
...@@ -170,7 +170,7 @@ void pmp_test() { ...@@ -170,7 +170,7 @@ void pmp_test() {
printf("line %d passed\n", __LINE__); printf("line %d passed\n", __LINE__);
// Case: amo to address protected by pmp (!w,r) // Case: amo to address protected by pmp (!w,r)
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
asm volatile( asm volatile(
"li s4, 0xb0004000;" "li s4, 0xb0004000;"
"amoadd.d s5, s6, (s4);" "amoadd.d s5, s6, (s4);"
...@@ -183,12 +183,12 @@ void pmp_test() { ...@@ -183,12 +183,12 @@ void pmp_test() {
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH) #elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
// TODO: update pmp test for southlake // TODO: update pmp test for southlake
store_access_fault_to_be_reported = 0; pmp_store_access_fault_to_be_reported = 0;
int *b = (int *)(0x2030000000UL); int *b = (int *)(0x2030000000UL);
*b = 1; // should not trigger a fault *b = 1; // should not trigger a fault
result_check(); result_check();
store_access_fault_to_be_reported = 1; pmp_store_access_fault_to_be_reported = 1;
volatile int *a = (int *)(0x2010000040UL); volatile int *a = (int *)(0x2010000040UL);
*a = 1; // should trigger a fault *a = 1; // should trigger a fault
result_check(); result_check();
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
* RISC-V 64 SV39 Virutal Memory test * RISC-V 64 SV39 Virutal Memory test
*/ */
#define EXCEPTION_LOAD_ACCESS_FAULT 5
#define EXCEPTION_STORE_ACCESS_FAULT 7
#define EXCEPTION_LOAD_PAGE_FAULT 13 #define EXCEPTION_LOAD_PAGE_FAULT 13
#define EXCEPTION_STORE_PAGE_FAULT 15 #define EXCEPTION_STORE_PAGE_FAULT 15
...@@ -17,7 +19,11 @@ static char *sv39_alloc_base = (char *)(0x2040000000UL); ...@@ -17,7 +19,11 @@ static char *sv39_alloc_base = (char *)(0x2040000000UL);
// invalid arch // invalid arch
#endif #endif
uint64_t page_fault_to_be_reported = 0; volatile uint64_t load_page_fault_to_be_reported = 0;
volatile uint64_t store_page_fault_to_be_reported = 0;
volatile uint64_t load_access_fault_to_be_reported = 0;
volatile uint64_t store_access_fault_to_be_reported = 0;
inline int inst_is_compressed(uint64_t addr){ inline int inst_is_compressed(uint64_t addr){
uint8_t byte = *(uint8_t*)addr; uint8_t byte = *(uint8_t*)addr;
...@@ -26,20 +32,40 @@ inline int inst_is_compressed(uint64_t addr){ ...@@ -26,20 +32,40 @@ inline int inst_is_compressed(uint64_t addr){
_Context* store_page_fault_handler(_Event* ev, _Context *c) { _Context* store_page_fault_handler(_Event* ev, _Context *c) {
printf("store page fault triggered\n"); printf("store page fault triggered\n");
if(!page_fault_to_be_reported){ if(!store_page_fault_to_be_reported){
_halt(1); // something went wrong _halt(1); // something went wrong
} }
page_fault_to_be_reported = 0; store_page_fault_to_be_reported = 0;
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4; c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
return c; return c;
} }
_Context* load_page_fault_handler(_Event* ev, _Context *c) { _Context* load_page_fault_handler(_Event* ev, _Context *c) {
printf("load page fault triggered\n"); printf("load page fault triggered\n");
if(!page_fault_to_be_reported){ if(!load_page_fault_to_be_reported){
_halt(1); // something went wrong
}
load_page_fault_to_be_reported = 0;
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
return c;
}
_Context* load_access_fault_handler(_Event* ev, _Context *c) {
printf("load access fault triggered\n");
if(!load_access_fault_to_be_reported){
_halt(1); // something went wrong _halt(1); // something went wrong
} }
page_fault_to_be_reported = 0; load_access_fault_to_be_reported = 0;
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
return c;
}
_Context* store_access_fault_handler(_Event* ev, _Context *c) {
printf("store access fault triggered\n");
if(!store_access_fault_to_be_reported){
_halt(1); // something went wrong
}
store_access_fault_to_be_reported = 0;
c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4; c->sepc = inst_is_compressed(c->sepc) ? c->sepc + 2: c->sepc + 4;
return c; return c;
} }
...@@ -94,17 +120,144 @@ void sv39_test() { ...@@ -94,17 +120,144 @@ void sv39_test() {
assert(*r_ptr == 'a'); assert(*r_ptr == 'a');
printf("test sv39 store page fault\n"); printf("test sv39 store page fault\n");
page_fault_to_be_reported = 1; store_page_fault_to_be_reported = 1;
*fault_ptr = 'b'; // store: not compressed *fault_ptr = 'b';
if(page_fault_to_be_reported){ if(store_page_fault_to_be_reported){
_halt(1); _halt(1);
} }
printf("test sv39 load page fault\n"); printf("test sv39 load page fault\n");
page_fault_to_be_reported = 1; load_page_fault_to_be_reported = 1;
*w_ptr = *fault_ptr; *w_ptr = *fault_ptr;
if(page_fault_to_be_reported){ if(load_page_fault_to_be_reported){
_halt(1); _halt(1);
} }
_halt(0); _halt(0);
} }
/*
* RISC-V 64 SV39 Hugepage + Hugepage Atom Inst test
*/
void sv39_hp_atom_test() {
printf("start sv39 hugepage atom test\n");
_vme_init(sv39_pgalloc, sv39_pgfree);
printf("sv39 setup done\n");
#if defined(__ARCH_RISCV64_NOOP) || defined(__ARCH_RISCV32_NOOP) || defined(__ARCH_RISCV64_XS)
_map(&kas, (void *)0x900000000UL, (void *)0x80200000, PTE_R | PTE_A | PTE_D);
// allocate a metapage, not protected by pmp
_map_rv_hugepage(&kas, (void *)0xa00000000UL, (void *)0x80200000, PTE_W | PTE_R | PTE_A | PTE_D, 1);
// allocate a metapage, not protected by pmp, without write perm
_map_rv_hugepage(&kas, (void *)0xb00000000UL, (void *)0x80200000, PTE_R | PTE_A | PTE_D, 1);
// allocate a metapage, not protected by pmp, without read perm
_map_rv_hugepage(&kas, (void *)0xc00000000UL, (void *)0x80200000, PTE_W | PTE_A | PTE_D, 1);
// allocate a metapage, protected by pmp (!rw)
_map_rv_hugepage(&kas, (void *)0xd00000000UL, (void *)0xb0000000, PTE_W | PTE_R | PTE_A | PTE_D, 1);
char *normal_rw_ptr = (char *)(0x900000000UL);
char *hp_rw_ptr = (char *)(0xa00000000UL);
char *hp_r_ptr = (char *)(0xb00000000UL);
char *hp_w_ptr = (char *)(0xc00000000UL);
char *hp_pmp_ptr = (char *)(0xd00000000UL);
printf("memory map done\n");
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
// TODO
#else
// invalid arch
_halt(1);
#endif
irq_handler_reg(EXCEPTION_STORE_PAGE_FAULT, &store_page_fault_handler);
irq_handler_reg(EXCEPTION_LOAD_PAGE_FAULT, &load_page_fault_handler);
irq_handler_reg(EXCEPTION_STORE_ACCESS_FAULT, &store_access_fault_handler);
irq_handler_reg(EXCEPTION_LOAD_ACCESS_FAULT, &load_access_fault_handler);
printf("test sv39 hugepage data write\n");
*hp_rw_ptr = 'a';
printf("test sv39 hugepage data read\n");
assert(*hp_rw_ptr == 'a');
printf("test sv39 normalpage data read\n");
assert(*normal_rw_ptr == 'a');
printf("test sv39 hugepage store page fault\n");
store_page_fault_to_be_reported = 1;
*hp_r_ptr = 'b';
if(store_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage load page fault\n");
load_page_fault_to_be_reported = 1;
*hp_rw_ptr = *hp_w_ptr;
if(load_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage store access fault\n");
store_access_fault_to_be_reported = 1;
*hp_pmp_ptr = 'b';
if(store_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage load access fault\n");
load_access_fault_to_be_reported = 1;
*hp_rw_ptr = *hp_pmp_ptr;
if(load_access_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage atom store page fault\n");
store_page_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xb00000000;"
"amoadd.d s5, s6, (s4);"
:
:
:"s4","s5","s6"
);
if(store_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage atom load page fault\n");
load_page_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xc00000000;"
"lr.d s5, (s4);"
:
:
:"s4","s5","s6"
);
if(load_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage atom store access fault\n");
store_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xd00000000;"
"amoadd.d s5, s6, (s4);"
:
:
:"s4","s5","s6"
);
if(store_page_fault_to_be_reported){
_halt(1);
}
printf("test sv39 hugepage atom load access fault\n");
load_access_fault_to_be_reported = 1;
asm volatile(
"li s4, 0xd00000000;"
"lr.d s5, (s4);"
:
:
:"s4","s5","s6"
);
if(load_access_fault_to_be_reported){
_halt(1);
}
_halt(0);
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册