Add qemu 2.4.0
[kvmfornfv.git] / qemu / tests / tcg / xtensa / test_mmu.S
diff --git a/qemu/tests/tcg/xtensa/test_mmu.S b/qemu/tests/tcg/xtensa/test_mmu.S
new file mode 100644 (file)
index 0000000..a15316f
--- /dev/null
@@ -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