未验证 提交 3f2d7d7c 编写于 作者: B bugGenerator 提交者: GitHub

tests: add riscv64 ppn access fault test (#29)

......@@ -86,6 +86,9 @@ void _unprotect(_AddressSpace *as);
void _map(_AddressSpace *as, void *va, void *pa, int prot);
_Context *_ucontext(_AddressSpace *as, _Area kstack, void *entry);
// a fault map for xiangshan testing access fault
void _map_fault(_AddressSpace *as, void *va, void *pa, int prot);
// hugepage map for xiangshan testing
void _map_rv_hugepage(_AddressSpace *as, void *va, void *pa, int prot, int pagetable_level);
......
......@@ -172,6 +172,37 @@ void _map(_AddressSpace *as, void *va, void *pa, int prot) {
}
}
/*
* A wrong map to test access fault, high bits of ppn is not zero
* Only available for sv39 and paddr = 36! (ppnlen can not be changed)
*/
void _map_fault(_AddressSpace *as, void *va, void *pa, int prot) {
assert((uintptr_t)va % PGSIZE == 0);
assert((uintptr_t)pa % PGSIZE == 0);
PTE *pg_base = as->ptr;
PTE *pte;
int level;
uintptr_t max = 1;
for (int i = 0; i < 20; i++){
max *= 2;
}
uintptr_t randnum = rand() % (max - 1);
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 == 0) break;
if (!(*pte & PTE_V)) {
pg_base = new_page();
*pte = PTE_V | (PN(pg_base) << 10);
}
}
if (!(*pte & PTE_V)) {
*pte = PTE_V | prot | (PN(pa) << 10) | (randnum << 34);
}
}
/*
* map va to pa with prot permission with page table root as
* pagetable_level indicates page table level to be used
......
......@@ -38,6 +38,7 @@ int main(const char *args) {
CASE('c', pmp_test, CTE(simple_trap));
CASE('s', sv39_test, IOE, CTE(simple_trap));
CASE('f', sv39_hp_atom_test, IOE, CTE(simple_trap));
CASE('g', sv39_ppn_af_test, IOE, CTE(simple_trap))
CASE('b', cache_test);
CASE('r', rtc_accuracy_test);
case 'H':
......
......@@ -27,7 +27,7 @@ volatile uint64_t store_access_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) {
......@@ -135,6 +135,73 @@ void sv39_test() {
_halt(0);
}
/*
* RISC-V 64 SV39 raise access fault when high 20 bits of ppn is not zero
*/
void sv39_ppn_af_test() {
printf("start sv39 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 *)0x80020000, PTE_W | PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0xa00000000UL, (void *)0x80020000, PTE_W | PTE_R | PTE_A | PTE_D);
uint64_t addr = 0xb00000000UL;
for (int i = 0; i < 100; i++) {
_map_fault(&kas, (void *)(addr + 0x1000 * i), (void *)0x80020000, PTE_W | PTE_R | PTE_A | PTE_D);
}
printf("memory map done\n");
char *w_ptr = (char *)(0xa00000000UL);
char *r_ptr = (char *)(0x900000000UL);
char *fault_ptr[100] = {0};
for (int i = 0; i < 100; i++) {
fault_ptr[i] = (char *)(addr + 0x1000 * i);
}
#elif defined(__ARCH_RISCV64_XS_SOUTHLAKE) || defined(__ARCH_RISCV64_XS_SOUTHLAKE_FLASH)
_map(&kas, (void *)0x2100000000UL, (void *)0x2000020000, PTE_W | PTE_R | PTE_A | PTE_D);
_map(&kas, (void *)0x2200000000UL, (void *)0x2000020000, PTE_W | PTE_R | PTE_A | PTE_D);
uint64_t addr = 0x2300000000UL;
for (int i = 0; i < 100; i++) {
_map_fault(&kas, (void *)(addr + 0x1000 * i), (void *)0x2000020000, PTE_W | PTE_R | PTE_A | PTE_D);
}
printf("memory map done\n");
char *w_ptr = (char *)(0x2100000000UL);
char *r_ptr = (char *)(0x2200000000UL);
char *fault_ptr[100] = {0};
for (int i = 0; i < 100; i++) {
fault_ptr[i] = (char *)(addr + 0x1000 * i);
}}
#else
// invalid arch
_halt(1);
#endif
irq_handler_reg(EXCEPTION_STORE_ACCESS_FAULT, &store_access_fault_handler);
irq_handler_reg(EXCEPTION_LOAD_ACCESS_FAULT, &load_access_fault_handler);
asm volatile("sfence.vma");
printf("test sv39 data write\n");
*w_ptr = 'a';
printf("test sv39 data read\n");
assert(*r_ptr == 'a');
for (int i = 0; i < 100; i++) {
printf("test sv39 store access fault %d\n", i);
store_access_fault_to_be_reported = 1;
*fault_ptr[i] = 'b';
if(store_access_fault_to_be_reported){
_halt(1);
}
printf("test sv39 load access fault %d\n", i);
load_access_fault_to_be_reported = 1;
*w_ptr = *fault_ptr[i];
if(load_access_fault_to_be_reported){
_halt(1);
}
}
_halt(0);
}
/*
* RISC-V 64 SV39 Hugepage + Hugepage Atom Inst test
*/
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册