#include "macros.inc" test_suite mmu .purgem test_init .macro clean_tlb_way way, page_size, n_entries movi a2, \way movi a3, \page_size movi a4, \n_entries loop a4, 1f idtlb a2 iitlb a2 add a2, a2, a3 1: .endm .macro test_init clean_tlb_way 0, 0x00001000, 4 clean_tlb_way 1, 0x00001000, 4 clean_tlb_way 2, 0x00001000, 4 clean_tlb_way 3, 0x00001000, 4 clean_tlb_way 4, 0x00100000, 4 movi a2, 0x00000007 idtlb a2 movi a2, 0x00000008 idtlb a2 movi a2, 0x00000009 idtlb a2 .endm test tlb_group movi a2, 0x04000002 /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 witlb a2, a3 movi a3, 0x00200004 rdtlb0 a1, a3 ritlb0 a2, a3 movi a3, 0x01000001 assert eq, a1, a3 assert eq, a2, a3 movi a3, 0x00200004 rdtlb1 a1, a3 ritlb1 a2, a3 movi a3, 0x04000002 assert eq, a1, a3 assert eq, a2, a3 movi a3, 0x01234567 pdtlb a1, a3 pitlb a2, a3 movi a3, 0x01234014 assert eq, a1, a3 movi a3, 0x0123400c assert eq, a2, a3 movi a3, 0x00200004 idtlb a3 iitlb a3 movi a3, 0x01234567 pdtlb a1, a3 pitlb a2, a3 movi a3, 0x00000010 and a1, a1, a3 assert eqi, a1, 0 movi a3, 0x00000008 and a2, a2, a3 assert eqi, a2, 0 test_end test itlb_miss set_vector kernel, 1f movi a3, 0x00100000 jx a3 test_fail 1: rsr a2, excvaddr assert eq, a2, a3 rsr a2, exccause movi a3, 16 assert eq, a2, a3 test_end test dtlb_miss set_vector kernel, 1f movi a3, 0x00100000 l8ui a2, a3, 0 test_fail 1: rsr a2, excvaddr assert eq, a2, a3 rsr a2, exccause movi a3, 24 assert eq, a2, a3 test_end test itlb_multi_hit set_vector kernel, 1f movi a2, 0x04000002 /* PPN */ movi a3, 0xf0000004 /* VPN */ witlb a2, a3 movi a3, 0xf0000000 pitlb a2, a3 test_fail 1: rsr a2, exccause movi a3, 17 assert eq, a2, a3 test_end test dtlb_multi_hit set_vector kernel, 1f movi a2, 0x04000002 /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 movi a3, 0x01200007 /* VPN */ wdtlb a2, a3 movi a3, 0x01200000 pdtlb a2, a3 test_fail 1: rsr a2, exccause movi a3, 25 assert eq, a2, a3 test_end test inst_fetch_privilege set_vector kernel, 3f movi a2, 0x4004f wsr a2, ps 1: isync nop 2: test_fail 3: movi a1, 1b rsr a2, excvaddr rsr a3, epc1 assert ge, a2, a1 assert ge, a3, a1 movi a1, 2b assert lt, a2, a1 assert lt, a3, a1 rsr a2, exccause movi a3, 18 assert eq, a2, a3 rsr a2, ps movi a3, 0x4005f assert eq, a2, a3 test_end test load_store_privilege set_vector kernel, 2f movi a3, 10f pitlb a3, a3 ritlb1 a2, a3 movi a1, 0x10 or a2, a2, a1 movi a1, 0x000ff000 and a3, a3, a1 movi a1, 4 or a3, a3, a1 witlb a2, a3 movi a3, 10f movi a1, 0x000fffff and a1, a3, a1 movi a2, 0x04000003 /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 movi a3, 0x01200001 movi a2, 0x4004f jx a1 10: wsr a2, ps isync 1: l8ui a2, a3, 0 test_fail 2: rsr a2, excvaddr assert eq, a2, a3 rsr a2, epc1 movi a3, 1b movi a1, 0x000fffff and a3, a3, a1 assert eq, a2, a3 rsr a2, exccause movi a3, 26 assert eq, a2, a3 rsr a2, ps movi a3, 0x4005f assert eq, a2, a3 test_end test cring_load_store_privilege set_vector kernel, 0 set_vector double, 2f movi a2, 0x04000003 /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 movi a3, 0x01200004 movi a2, 0x4005f /* ring 1 + excm => cring == 0 */ wsr a2, ps isync l8ui a2, a3, 0 /* cring used */ 1: l32e a2, a3, -4 /* ring used */ test_fail 2: rsr a2, excvaddr addi a2, a2, 4 assert eq, a2, a3 rsr a2, depc movi a3, 1b assert eq, a2, a3 rsr a2, exccause movi a3, 26 assert eq, a2, a3 rsr a2, ps movi a3, 0x4005f assert eq, a2, a3 test_end test inst_fetch_prohibited set_vector kernel, 2f movi a3, 10f pitlb a3, a3 ritlb1 a2, a3 movi a1, 0xfffff000 and a2, a2, a1 movi a1, 0x4 or a2, a2, a1 movi a1, 0x000ff000 and a3, a3, a1 movi a1, 4 or a3, a3, a1 witlb a2, a3 movi a3, 10f movi a1, 0x000fffff and a1, a3, a1 jx a1 .align 4 10: nop test_fail 2: rsr a2, excvaddr assert eq, a2, a1 rsr a2, epc1 assert eq, a2, a1 rsr a2, exccause movi a3, 20 assert eq, a2, a3 test_end test load_prohibited set_vector kernel, 2f movi a2, 0x0400000c /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 movi a3, 0x01200002 1: l8ui a2, a3, 0 test_fail 2: rsr a2, excvaddr assert eq, a2, a3 rsr a2, epc1 movi a3, 1b assert eq, a2, a3 rsr a2, exccause movi a3, 28 assert eq, a2, a3 test_end test store_prohibited set_vector kernel, 2f movi a2, 0x04000001 /* PPN */ movi a3, 0x01200004 /* VPN */ wdtlb a2, a3 movi a3, 0x01200003 l8ui a2, a3, 0 1: s8i a2, a3, 0 test_fail 2: rsr a2, excvaddr assert eq, a2, a3 rsr a2, epc1 movi a3, 1b assert eq, a2, a3 rsr a2, exccause movi a3, 29 assert eq, a2, a3 test_end /* Set up page table entry vaddr->paddr, ring=pte_ring, attr=pte_attr * and DTLB way 7 to cover this PTE, ring=pt_ring, attr=pt_attr */ .macro pt_setup pt_ring, pt_attr, pte_ring, vaddr, paddr, pte_attr movi a2, 0x80000000 wsr a2, ptevaddr movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ movi a4, 0x04000003 | ((\pt_ring) << 4) /* PADDR 64M */ wdtlb a4, a3 isync movi a3, ((\paddr) & 0xfffff000) | ((\pte_ring) << 4) | (\pte_attr) movi a1, ((\vaddr) >> 12) << 2 add a2, a1, a2 s32i a3, a2, 0 movi a3, 0x80000007 | (((\vaddr) >> 10) & 0xfffff000) /* way 7 */ movi a4, 0x04000000 | ((\pt_ring) << 4) | (\pt_attr) /* PADDR 64M */ wdtlb a4, a3 isync movi a3, (\vaddr) .endm /* out: PS.RING=ring, PS.EXCM=excm, a3=vaddr */ .macro go_ring ring, excm, vaddr movi a3, 10f pitlb a3, a3 ritlb1 a2, a3 movi a1, 0x10 or a2, a2, a1 movi a1, 0x000ff000 and a3, a3, a1 movi a1, 4 or a3, a3, a1 witlb a2, a3 movi a3, 10f movi a1, 0x000fffff and a1, a3, a1 movi a2, 0 wsr a2, excvaddr movi a3, \vaddr movi a2, 0x4000f | ((\ring) << 6) | ((\excm) << 4) jx a1 10: wsr a2, ps isync .endm /* in: a3 -- virtual address to test */ .macro assert_auto_tlb movi a2, 0x4000f wsr a2, ps isync pdtlb a2, a3 movi a1, 0xfffff01f and a2, a2, a1 movi a1, 0xfffff000 and a1, a1, a3 xor a1, a1, a2 assert gei, a1, 0x10 movi a2, 0x14 assert lt, a1, a2 .endm /* in: a3 -- virtual address to test */ .macro assert_no_auto_tlb movi a2, 0x4000f wsr a2, ps isync pdtlb a2, a3 movi a1, 0x10 and a1, a1, a2 assert eqi, a1, 0 .endm .macro assert_sr sr, v rsr a2, \sr movi a1, (\v) assert eq, a1, a2 .endm .macro assert_epc1_1m vaddr movi a2, (\vaddr) movi a1, 0xfffff and a1, a1, a2 rsr a2, epc1 assert eq, a1, a2 .endm test dtlb_autoload set_vector kernel, 0 pt_setup 0, 3, 1, 0x1000, 0x1000, 3 assert_no_auto_tlb l8ui a1, a3, 0 rsr a2, excvaddr assert eq, a2, a3 assert_auto_tlb test_end test autoload_load_store_privilege set_vector kernel, 0 set_vector double, 2f pt_setup 0, 3, 0, 0x2000, 0x2000, 3 movi a3, 0x2004 assert_no_auto_tlb movi a2, 0x4005f /* ring 1 + excm => cring == 0 */ wsr a2, ps isync 1: l32e a2, a3, -4 /* ring used */ test_fail 2: rsr a2, excvaddr addi a1, a3, -4 assert eq, a1, a2 assert_auto_tlb assert_sr depc, 1b assert_sr exccause, 26 test_end test autoload_pte_load_prohibited set_vector kernel, 2f pt_setup 0, 3, 0, 0x3000, 0, 0xc assert_no_auto_tlb 1: l32i a2, a3, 0 test_fail 2: rsr a2, excvaddr assert eq, a2, a3 assert_auto_tlb assert_sr epc1, 1b assert_sr exccause, 28 test_end test autoload_pt_load_prohibited set_vector kernel, 2f pt_setup 0, 0xc, 0, 0x4000, 0x4000, 3 assert_no_auto_tlb 1: l32i a2, a3, 0 test_fail 2: rsr a2, excvaddr assert eq, a2, a3 assert_no_auto_tlb assert_sr epc1, 1b assert_sr exccause, 24 test_end test autoload_pt_privilege set_vector kernel, 2f pt_setup 0, 3, 1, 0x5000, 0, 3 go_ring 1, 0, 0x5001 l8ui a2, a3, 0 1: syscall 2: rsr a2, excvaddr assert eq, a2, a3 assert_auto_tlb assert_epc1_1m 1b assert_sr exccause, 1 test_end test autoload_pte_privilege set_vector kernel, 2f pt_setup 0, 3, 0, 0x6000, 0, 3 go_ring 1, 0, 0x6001 1: l8ui a2, a3, 0 syscall 2: rsr a2, excvaddr assert eq, a2, a3 assert_auto_tlb assert_epc1_1m 1b assert_sr exccause, 26 test_end test autoload_3_level_pt set_vector kernel, 2f pt_setup 1, 3, 1, 0x00400000, 0, 3 pt_setup 1, 3, 1, 0x80001000, 0x2000000, 3 go_ring 1, 0, 0x00400001 1: l8ui a2, a3, 0 syscall 2: rsr a2, excvaddr assert eq, a2, a3 assert_no_auto_tlb assert_epc1_1m 1b assert_sr exccause, 24 test_end test cross_page_insn set_vector kernel, 2f movi a2, 0x04000003 /* PPN */ movi a3, 0x00007000 /* VPN */ witlb a2, a3 wdtlb a2, a3 movi a3, 0x00008000 /* VPN */ witlb a2, a3 wdtlb a2, a3 movi a2, 0x00007fff movi a3, 20f movi a4, 21f sub a4, a4, a3 loop a4, 1f l8ui a5, a3, 0 s8i a5, a2, 0 addi a2, a2, 1 addi a3, a3, 1 1: movi a2, 0x00007fff movi a3, 0x00008000 /* DTLB: OK, ITLB: OK */ jx a2 .begin no-transform 20: l32i a2, a3, 0 syscall 21: .end no-transform 2: rsr a2, exccause movi a3, 1 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x8002 assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007fff assert ne, a2, a3 reset_ps set_vector kernel, 3f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ wdtlb a2, a3 movi a2, 0x00007fff movi a3, 0x00008000 /* DTLB: FAIL, ITLB: OK */ jx a2 3: rsr a2, exccause movi a3, 28 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7fff assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007fff assert eq, a2, a3 reset_ps set_vector kernel, 4f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ witlb a2, a3 movi a2, 0x04000003 /* PPN */ wdtlb a2, a3 movi a2, 0x00007fff movi a3, 0x00008000 /* DTLB: OK, ITLB: FAIL */ jx a2 4: rsr a2, exccause movi a3, 20 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7fff assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007fff assert eq, a2, a3 reset_ps set_vector kernel, 5f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ wdtlb a2, a3 movi a2, 0x00007fff movi a3, 0x00008000 /* DTLB: FAIL, ITLB: FAIL */ jx a2 5: rsr a2, exccause movi a3, 20 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7fff assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007fff assert eq, a2, a3 test_end test cross_page_tb set_vector kernel, 2f movi a2, 0x04000003 /* PPN */ movi a3, 0x00007000 /* VPN */ witlb a2, a3 wdtlb a2, a3 movi a3, 0x00008000 /* VPN */ witlb a2, a3 wdtlb a2, a3 movi a2, 0x00007ffc movi a3, 20f movi a4, 21f sub a4, a4, a3 loop a4, 1f l8ui a5, a3, 0 s8i a5, a2, 0 addi a2, a2, 1 addi a3, a3, 1 1: movi a2, 0x00007ffc movi a3, 0x00008000 /* DTLB: OK, ITLB: OK */ jx a2 .begin no-transform 20: l32i a2, a3, 0 syscall 21: .end no-transform 2: rsr a2, exccause movi a3, 1 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7fff assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007ffc assert ne, a2, a3 reset_ps set_vector kernel, 3f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ wdtlb a2, a3 movi a2, 0x00007ffc movi a3, 0x00008000 /* DTLB: FAIL, ITLB: OK */ jx a2 3: rsr a2, exccause movi a3, 28 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7ffc assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007ffc assert eq, a2, a3 reset_ps set_vector kernel, 4f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ witlb a2, a3 movi a2, 0x04000003 /* PPN */ wdtlb a2, a3 movi a2, 0x00007ffc movi a3, 0x00008000 /* DTLB: OK, ITLB: FAIL */ jx a2 4: rsr a2, exccause movi a3, 20 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7fff assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007ffc assert ne, a2, a3 reset_ps set_vector kernel, 5f movi a2, 0x0400000c /* PPN */ movi a3, 0x00008000 /* VPN */ wdtlb a2, a3 movi a2, 0x00007ffc movi a3, 0x00008000 /* DTLB: FAIL, ITLB: FAIL */ jx a2 5: rsr a2, exccause movi a3, 28 assert eq, a2, a3 rsr a2, epc1 movi a3, 0x7ffc assert eq, a2, a3 rsr a2, excsave1 movi a3, 0x00007ffc assert eq, a2, a3 test_end test_suite_end