diff --git a/encoding.h b/encoding.h index 2aa895b..b0bdbf6 100644 --- a/encoding.h +++ b/encoding.h @@ -22,6 +22,10 @@ #define MSTATUS_TVM 0x00100000 #define MSTATUS_TW 0x00200000 #define MSTATUS_TSR 0x00400000 +#define MSTATUS_UFCFIEN 0x00800000 /* Zisslpcfi-.01 */ +#define MSTATUS_UBCFIEN 0x01000000 /* Zisslpcfi-.01 */ +#define MSTATUS_SPELP 0x02000000 /* Zisslpcfi-.01 */ +#define MSTATUS_MPELP 0x04000000 /* Zisslpcfi-.01 */ #define MSTATUS32_SD 0x80000000 #define MSTATUS_UXL 0x0000000300000000 #define MSTATUS_SXL 0x0000000C00000000 @@ -37,6 +41,11 @@ #define SSTATUS_XS 0x00018000 #define SSTATUS_SUM 0x00040000 #define SSTATUS_MXR 0x00080000 +#define SSTATUS_UFCFIEN MSTATUS_UFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SFCFIEN MSTATUS_SFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_UBCFIEN MSTATUS_UBCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SBCFIEN MSTATUS_SFCFIEN /* Zisslpcfi-.01 */ +#define SSTATUS_SPELP MSTATUS_SPELP /* Zisslpcfi-.01 */ #define SSTATUS32_SD 0x80000000 #define SSTATUS_UXL 0x0000000300000000 #define SSTATUS64_SD 0x8000000000000000 @@ -115,6 +124,14 @@ #define SIP_SSIP MIP_SSIP #define SIP_STIP MIP_STIP +/* CFI CSR bits */ +#define CFISTATUS_M_MASK (MSTATUS_MFCFIEN | MSTATUS_SFCFIEN | MSTATUS_SBCFIEN | \ + MSTATUS_UFCFIEN | MSTATUS_UBCFIEN | MSTATUS_MPELP | \ + MSTATUS_SPELP) +#define CFISTATUS_S_MASK (SSTATUS_SFCFIEN | SSTATUS_SBCFIEN | SSTATUS_UFCFIEN | \ + SSTATUS_UBCFIEN | SSTATUS_SPELP) +#define MENVCFG_CFI (1UL<<60) + #define PRV_U 0 #define PRV_S 1 #define PRV_H 2 @@ -1586,15 +1603,19 @@ #define CSR_USTATUS 0x0 #define CSR_UIE 0x4 #define CSR_UTVEC 0x5 +#define CSR_LPLR 0x6 #define CSR_VSTART 0x8 #define CSR_VXSAT 0x9 #define CSR_VXRM 0xa #define CSR_VCSR 0xf +#define CSR_SSP 0x20 #define CSR_USCRATCH 0x40 #define CSR_UEPC 0x41 #define CSR_UCAUSE 0x42 #define CSR_UTVAL 0x43 #define CSR_UIP 0x44 +#define CSR_MENVCFG 0x30A +#define CSR_HENVCFG 0x60A #define CSR_CYCLE 0xc00 #define CSR_TIME 0xc01 #define CSR_INSTRET 0xc02 @@ -2812,6 +2833,7 @@ DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) +DECLARE_CSR(ussp, CSR_USSP) #endif #ifdef DECLARE_CAUSE DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) diff --git a/p/riscv_test.h b/p/riscv_test.h index a08f49e..d35d73d 100644 --- a/p/riscv_test.h +++ b/p/riscv_test.h @@ -153,6 +153,8 @@ #define EXTRA_TVEC_MACHINE #define EXTRA_INIT #define EXTRA_INIT_TIMER +#define FILTER_TRAP +#define FILTER_PAGE_FAULT #define INTERRUPT_HANDLER j other_exception /* No interrupts should occur */ diff --git a/v/riscv_test.h b/v/riscv_test.h index c74e05d..e39123c 100644 --- a/v/riscv_test.h +++ b/v/riscv_test.h @@ -24,6 +24,16 @@ extra_boot: \ EXTRA_INIT \ ret; \ +.global trap_filter; \ +trap_filter: \ + FILTER_TRAP \ + li a0, 0; \ + ret; \ +.global pf_filter; \ +pf_filter: \ + FILTER_PAGE_FAULT \ + li a0, 0; \ + ret; \ .global userstart; \ userstart: \ init diff --git a/v/vm.c b/v/vm.c index 9802fb7..ac431a7 100644 --- a/v/vm.c +++ b/v/vm.c @@ -6,6 +6,8 @@ #include "riscv_test.h" +#define Sv48 + #if __riscv_xlen == 32 # define SATP_MODE_CHOICE SATP_MODE_SV32 #elif defined(Sv48) @@ -136,8 +138,19 @@ static void evict(unsigned long addr) } } -void handle_fault(uintptr_t addr, uintptr_t cause) +extern int pf_filter(uintptr_t addr, uintptr_t *pte, int *copy); +extern int trap_filter(trapframe_t *tf); + +void handle_fault(uintptr_t addr, uintptr_t cause, trapframe_t* tf) { + cputstring("\nhandle_fault for address and PC : "); + cputstring("\n"); + printhex(addr); + cputstring("\n"); + printhex(tf->epc); + int copy_page = 1; + uintptr_t filter_encodings = 0; + assert(addr >= PGSIZE && addr < MAX_TEST_PAGES * PGSIZE); addr = addr/PGSIZE*PGSIZE; @@ -159,24 +172,61 @@ void handle_fault(uintptr_t addr, uintptr_t cause) freelist_tail = 0; uintptr_t new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | PTE_V | PTE_U | PTE_R | PTE_W | PTE_X; + + if (pf_filter(addr, &filter_encodings, ©_page)) { + cputstring("pf_filter returned true\n"); + new_pte = (node->addr >> PGSHIFT << PTE_PPN_SHIFT) | filter_encodings; + } + user_llpt[addr/PGSIZE] = new_pte | PTE_A | PTE_D; flush_page(addr); assert(user_mapping[addr/PGSIZE].addr == 0); user_mapping[addr/PGSIZE] = *node; - uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM); - memcpy((void*)addr, uva2kva(addr), PGSIZE); - write_csr(sstatus, sstatus); + if (copy_page) { + uintptr_t sstatus = set_csr(sstatus, SSTATUS_SUM); + memcpy((void*)addr, uva2kva(addr), PGSIZE); + write_csr(sstatus, sstatus); + } user_llpt[addr/PGSIZE] = new_pte; flush_page(addr); asm volatile ("fence.i"); + cputstring("returning from handle_fault\n"); } void handle_trap(trapframe_t* tf) { + if (trap_filter(tf)) { + cputstring("trap_filter returned true, trap cause "); + printhex(tf->cause); + cputstring("\n epc "); + printhex(tf->epc); + cputstring("\n"); + /* + * trap_filter returning true and + * cause being ecall means, one of the test went wrong + */ + if (tf->cause == CAUSE_USER_ECALL) { + cputstring("\nTest failed test # "); + printhex(tf->gpr[3]); /* x3 holds testnum */ + cputstring("\nEPC # "); + printhex(tf->epc); + cputstring("\nt1/x6 val "); + terminate(0xbaddeed); + } + pop_tf(tf); + } else { + cputstring("! trap_filter returned false, trap cause "); + printhex(tf->cause); + cputstring("\n epc "); + printhex(tf->epc); + cputstring("\n"); + + } + if (tf->cause == CAUSE_USER_ECALL) { int n = tf->gpr[10]; @@ -189,18 +239,17 @@ void handle_trap(trapframe_t* tf) else if (tf->cause == CAUSE_ILLEGAL_INSTRUCTION) { assert(tf->epc % 4 == 0); - + int faulting_opcode = read_csr(stval); int* fssr; asm ("jal %0, 1f; fssr x0; 1:" : "=r"(fssr)); - - if (*(int*)tf->epc == *fssr) + if (faulting_opcode == *fssr) terminate(1); // FP test on non-FP hardware. "succeed." - else + else assert(!"illegal instruction"); tf->epc += 4; } else if (tf->cause == CAUSE_FETCH_PAGE_FAULT || tf->cause == CAUSE_LOAD_PAGE_FAULT || tf->cause == CAUSE_STORE_PAGE_FAULT) - handle_fault(tf->badvaddr, tf->cause); + handle_fault(tf->badvaddr, tf->cause, tf); else assert(!"unexpected exception"); @@ -225,7 +274,10 @@ static void coherence_torture() void vm_boot(uintptr_t test_addr) { + cputstring ("Entered vm_boot \n"); uint64_t random = ENTROPY; + unsigned int m_status = 0; + if (read_csr(mhartid) > 0) coherence_torture(); @@ -277,9 +329,15 @@ void vm_boot(uintptr_t test_addr) (1 << CAUSE_USER_ECALL) | (1 << CAUSE_FETCH_PAGE_FAULT) | (1 << CAUSE_LOAD_PAGE_FAULT) | - (1 << CAUSE_STORE_PAGE_FAULT)); + (1 << CAUSE_STORE_PAGE_FAULT) | + (1 << CAUSE_STORE_ACCESS) | + (1 << CAUSE_LOAD_ACCESS) | + (1 << CAUSE_ILLEGAL_INSTRUCTION)); + + m_status = read_csr(mstatus); // FPU on; accelerator on; vector unit on - write_csr(mstatus, MSTATUS_FS | MSTATUS_XS | MSTATUS_VS); + m_status |= (MSTATUS_FS | MSTATUS_XS | MSTATUS_VS); + write_csr(mstatus, m_status); write_csr(mie, 0); random = 1 + (random % MAX_TEST_PAGES);