diff options
Diffstat (limited to 'qemu/tests/tcg/xtensa/test_mmu.S')
-rw-r--r-- | qemu/tests/tcg/xtensa/test_mmu.S | 743 |
1 files changed, 743 insertions, 0 deletions
diff --git a/qemu/tests/tcg/xtensa/test_mmu.S b/qemu/tests/tcg/xtensa/test_mmu.S new file mode 100644 index 000000000..a15316ffb --- /dev/null +++ b/qemu/tests/tcg/xtensa/test_mmu.S @@ -0,0 +1,743 @@ +#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 |