/ test / asm / mtval.asm
mtval.asm
  1  # test `mtval` and `mcause` CSR values for various excpetions
  2  # C extension is required in the core, but must be disabled in the toolchain
  3  
  4      la x1, handler
  5      csrw mtvec, x1
  6      li x8, 0
  7  
  8      li x7, 0x80000000
  9  c0: # load from illegal address. mtval=addr mcause=LOAD_ACCESS_FAULT
 10      lw x1, 0x230(x7)
 11  c1: # mtval=pc mcause=BREAKPOINT
 12      ebreak
 13  c2: # instruction address out of memory mtval=i_out_of_range mcause=INSTRUCTION_ACCESS_FAULT
 14      j i_out_of_range
 15  c3: # jump to 2-byte aligned, 4-byte long instruction, of which first two bytes are available
 16      # and other half is outside of memory range. mtval=i_partial_out_of_range+2 mcause=INSTRUCTION_ACCESS_FAULT
 17      j i_partial_out_of_range
 18  c4: # illegal 4-byte instruction ([0:2] = 0b11) mtval=raw instruction mcause=ILLEGAL_INSTRUCTION
 19  .word 0x43
 20  c5: # illegal compressed type ([0:2] != 0b11) instruction mtval=raw instruction mcause=ILLEGAL_INSTRUCTION
 21  .word 0x4002
 22  c6: # access to missing csr mtval=raw instruction mcause=ILLEGAL_INSTRUCTION
 23      csrr x1, 0x123
 24  c7: # access to missing csr mtval=raw instruction mcause=ILLEGAL_INSTRUCTION
 25      csrwi 0x123, 8
 26  c8: # store to misaligned address mtval=addr mcause=STORE_ADDRESS_MISALIGNED
 27      sw x1, 0x231(x7)
 28  c9: # mtval=0 mcause=ENVIRONMENT_CALL_FROM_M
 29      ecall
 30  
 31  pass:
 32      j pass
 33  
 34  
 35  handler: # test each case. test case number = in x8>>2
 36      la x1, expected_mtval
 37      add x1, x1, x8
 38      lw x2, (x1)
 39      csrr x1, mtval
 40      bne x1, x2, fail
 41  
 42      la x1, expected_mcause
 43      add x1, x1, x8
 44      lw x2, (x1)
 45      csrr x1, mcause
 46      bne x1, x2, fail
 47  
 48      la x1, next_instr
 49      add x1, x1, x8
 50      lw x2, (x1)
 51      csrw mepc, x2
 52  
 53      addi x8, x8, 4
 54  
 55      mret
 56  
 57  fail:
 58      j fail
 59  
 60  # it is legal - C is enabled in core, but can't be enabled in toolchain to keep 4-byte nops
 61  .org 0x0FFE
 62  i_partial_out_of_range:
 63  nop
 64  i_out_of_range:
 65  nop
 66  
 67  .data
 68  
 69  expected_mtval:
 70  .word 0x80000230
 71  .word c1
 72  .word i_out_of_range
 73  .word i_partial_out_of_range + 2
 74  .word 0x43
 75  .word 0x4002
 76  .word 0x123020f3
 77  .word 0x12345073
 78  .word 0x80000231
 79  .word 0
 80  
 81  expected_mcause:
 82  .word 5
 83  .word 3
 84  .word 1
 85  .word 1
 86  .word 2
 87  .word 2
 88  .word 2
 89  .word 2
 90  .word 6
 91  .word 11
 92  # testing misaligned instr branch is not possible with C enabled :(
 93  
 94  next_instr:
 95  .word c1
 96  .word c2
 97  .word c3
 98  .word c4
 99  .word c5
100  .word c6
101  .word c7
102  .word c8
103  .word c9
104  .word pass