112771Sqtt2@cornell.edu# See LICENSE for license details.
212771Sqtt2@cornell.edu
312771Sqtt2@cornell.edu#*****************************************************************************
412771Sqtt2@cornell.edu# csr.S
512771Sqtt2@cornell.edu#-----------------------------------------------------------------------------
612771Sqtt2@cornell.edu#
712771Sqtt2@cornell.edu# Test CSRRx and CSRRxI instructions.
812771Sqtt2@cornell.edu#
912771Sqtt2@cornell.edu
1012771Sqtt2@cornell.edu#include "riscv_test.h"
1112771Sqtt2@cornell.edu#include "test_macros.h"
1212771Sqtt2@cornell.edu
1312771Sqtt2@cornell.eduRVTEST_RV64S
1412771Sqtt2@cornell.eduRVTEST_CODE_BEGIN
1512771Sqtt2@cornell.edu
1612771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
1712771Sqtt2@cornell.edu  #define sscratch mscratch
1812771Sqtt2@cornell.edu  #define sstatus mstatus
1912771Sqtt2@cornell.edu  #define scause mcause
2012771Sqtt2@cornell.edu  #define sepc mepc
2112771Sqtt2@cornell.edu  #define sret mret
2212771Sqtt2@cornell.edu  #define stvec_handler mtvec_handler
2312771Sqtt2@cornell.edu  #undef SSTATUS_SPP
2412771Sqtt2@cornell.edu  #define SSTATUS_SPP MSTATUS_MPP
2512771Sqtt2@cornell.edu#endif
2612771Sqtt2@cornell.edu
2712771Sqtt2@cornell.edu  # For RV64, make sure UXL encodes RV64.  (UXL does not exist for RV32.)
2812771Sqtt2@cornell.edu#if __riscv_xlen == 64
2912771Sqtt2@cornell.edu  # If running in M mode, use mstatus.MPP to check existence of U mode.
3012771Sqtt2@cornell.edu  # Otherwise, if in S mode, then U mode must exist and we don't need to check.
3112771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
3212771Sqtt2@cornell.edu  li t0, MSTATUS_MPP
3312771Sqtt2@cornell.edu  csrc mstatus, t0
3412771Sqtt2@cornell.edu  csrr t1, mstatus
3512771Sqtt2@cornell.edu  and t0, t0, t1
3612771Sqtt2@cornell.edu  bnez t0, 1f
3712771Sqtt2@cornell.edu#endif
3812771Sqtt2@cornell.edu  # If U mode is present, UXL should be 2 (XLEN = 64-bit)
3912771Sqtt2@cornell.edu  TEST_CASE(13, a0, SSTATUS_UXL & (SSTATUS_UXL << 1), csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
4012771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
4112771Sqtt2@cornell.edu  j 2f
4212771Sqtt2@cornell.edu1:
4312771Sqtt2@cornell.edu  # If U mode is not present, UXL should be 0
4412771Sqtt2@cornell.edu  TEST_CASE(14, a0, 0, csrr a0, sstatus; li a1, SSTATUS_UXL; and a0, a0, a1)
4512771Sqtt2@cornell.edu2:
4612771Sqtt2@cornell.edu#endif
4712771Sqtt2@cornell.edu#endif
4812771Sqtt2@cornell.edu
4912771Sqtt2@cornell.edu  csrwi sscratch, 3
5012771Sqtt2@cornell.edu  TEST_CASE( 2, a0,         3, csrr a0, sscratch);
5112771Sqtt2@cornell.edu  TEST_CASE( 3, a1,         3, csrrci a1, sscratch, 1);
5212771Sqtt2@cornell.edu  TEST_CASE( 4, a2,         2, csrrsi a2, sscratch, 4);
5312771Sqtt2@cornell.edu  TEST_CASE( 5, a3,         6, csrrwi a3, sscratch, 2);
5412771Sqtt2@cornell.edu  TEST_CASE( 6, a1,         2, li a0, 0xbad1dea; csrrw a1, sscratch, a0);
5512771Sqtt2@cornell.edu  TEST_CASE( 7, a0, 0xbad1dea, li a0, 0x0001dea; csrrc a0, sscratch, a0);
5612771Sqtt2@cornell.edu  TEST_CASE( 8, a0, 0xbad0000, li a0, 0x000beef; csrrs a0, sscratch, a0);
5712771Sqtt2@cornell.edu  TEST_CASE( 9, a0, 0xbadbeef, csrr a0, sscratch);
5812771Sqtt2@cornell.edu
5912771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
6012771Sqtt2@cornell.edu  # Is F extension present?
6112771Sqtt2@cornell.edu  csrr a0, misa
6212771Sqtt2@cornell.edu  andi a0, a0, (1 << ('F' - 'A'))
6312771Sqtt2@cornell.edu  beqz a0, 1f
6412771Sqtt2@cornell.edu  # If so, make sure FP stores have no effect when mstatus.FS is off.
6512771Sqtt2@cornell.edu  li a1, MSTATUS_FS
6612771Sqtt2@cornell.edu  csrs mstatus, a1
6712771Sqtt2@cornell.edu#ifdef __riscv_flen
6812771Sqtt2@cornell.edu  fmv.s.x f0, x0
6912771Sqtt2@cornell.edu  csrc mstatus, a1
7012771Sqtt2@cornell.edu  la a1, fsw_data
7112771Sqtt2@cornell.edu  TEST_CASE(10, a0, 1, fsw f0, (a1); lw a0, (a1));
7212771Sqtt2@cornell.edu#else
7312771Sqtt2@cornell.edu  # Fail if this test is compiled without F but executed on a core with F.
7412771Sqtt2@cornell.edu  TEST_CASE(10, zero, 1)
7512771Sqtt2@cornell.edu#endif
7612771Sqtt2@cornell.edu1:
7712771Sqtt2@cornell.edu
7812771Sqtt2@cornell.edu  # Figure out if 'U' is set in misa
7912771Sqtt2@cornell.edu  csrr a0, misa   # a0 = csr(misa)
8012771Sqtt2@cornell.edu  srli a0, a0, 20 # a0 = a0 >> 20
8112771Sqtt2@cornell.edu  andi a0, a0, 1  # a0 = a0 & 1
8212771Sqtt2@cornell.edu  beqz a0, finish # if no user mode, skip the rest of these checks
8312771Sqtt2@cornell.edu#endif /* __MACHINE_MODE */
8412771Sqtt2@cornell.edu
8512771Sqtt2@cornell.edu  # jump to user land
8612771Sqtt2@cornell.edu  li t0, SSTATUS_SPP
8712771Sqtt2@cornell.edu  csrc sstatus, t0
8812771Sqtt2@cornell.edu  la t0, 1f
8912771Sqtt2@cornell.edu  csrw sepc, t0
9012771Sqtt2@cornell.edu  sret
9112771Sqtt2@cornell.edu  1:
9212771Sqtt2@cornell.edu
9312771Sqtt2@cornell.edu  # Make sure writing the cycle counter causes an exception.
9412771Sqtt2@cornell.edu  # Don't run in supervisor, as we don't delegate illegal instruction traps.
9512771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
9612771Sqtt2@cornell.edu  TEST_CASE(11, a0, 255, li a0, 255; csrrw a0, cycle, x0);
9712771Sqtt2@cornell.edu#endif
9812771Sqtt2@cornell.edu
9912771Sqtt2@cornell.edu  # Make sure reading status in user mode causes an exception.
10012771Sqtt2@cornell.edu  # Don't run in supervisor, as we don't delegate illegal instruction traps.
10112771Sqtt2@cornell.edu#ifdef __MACHINE_MODE
10212771Sqtt2@cornell.edu  TEST_CASE(12, a0, 255, li a0, 255; csrr a0, sstatus)
10312771Sqtt2@cornell.edu#else
10412771Sqtt2@cornell.edu  TEST_CASE(12, x0, 0, nop)
10512771Sqtt2@cornell.edu#endif
10612771Sqtt2@cornell.edu
10712771Sqtt2@cornell.edufinish:
10812771Sqtt2@cornell.edu  RVTEST_PASS
10912771Sqtt2@cornell.edu
11012771Sqtt2@cornell.edu  # We should only fall through to this if scall failed.
11112771Sqtt2@cornell.edu  TEST_PASSFAIL
11212771Sqtt2@cornell.edu
11312771Sqtt2@cornell.edu  .align 2
11412771Sqtt2@cornell.edu  .global stvec_handler
11512771Sqtt2@cornell.edustvec_handler:
11612771Sqtt2@cornell.edu  # Trapping on tests 10-12 is good news.
11712771Sqtt2@cornell.edu  # Note that since the test didn't complete, TESTNUM is smaller by 1.
11812771Sqtt2@cornell.edu  li t0, 9
11912771Sqtt2@cornell.edu  bltu TESTNUM, t0, 1f
12012771Sqtt2@cornell.edu  li t0, 11
12112771Sqtt2@cornell.edu  bleu TESTNUM, t0, privileged
12212771Sqtt2@cornell.edu1:
12312771Sqtt2@cornell.edu
12412771Sqtt2@cornell.edu  # catch RVTEST_PASS and kick it up to M-mode
12512771Sqtt2@cornell.edu  csrr t0, scause
12612771Sqtt2@cornell.edu  li t1, CAUSE_USER_ECALL
12712771Sqtt2@cornell.edu  bne t0, t1, fail
12812771Sqtt2@cornell.edu  RVTEST_PASS
12912771Sqtt2@cornell.edu
13012771Sqtt2@cornell.eduprivileged:
13112771Sqtt2@cornell.edu  # Make sure scause indicates a lack of privilege.
13212771Sqtt2@cornell.edu  csrr t0, scause
13312771Sqtt2@cornell.edu  li t1, CAUSE_ILLEGAL_INSTRUCTION
13412771Sqtt2@cornell.edu  bne t0, t1, fail
13512771Sqtt2@cornell.edu  # Return to user mode, but skip the trapping instruction.
13612771Sqtt2@cornell.edu  csrr t0, sepc
13712771Sqtt2@cornell.edu  addi t0, t0, 4
13812771Sqtt2@cornell.edu  csrw sepc, t0
13912771Sqtt2@cornell.edu  sret
14012771Sqtt2@cornell.edu
14112771Sqtt2@cornell.eduRVTEST_CODE_END
14212771Sqtt2@cornell.edu
14312771Sqtt2@cornell.edu  .data
14412771Sqtt2@cornell.eduRVTEST_DATA_BEGIN
14512771Sqtt2@cornell.edu
14612771Sqtt2@cornell.edufsw_data: .word 1
14712771Sqtt2@cornell.edu
14812771Sqtt2@cornell.eduRVTEST_DATA_END
149