1*** Variables ***
2${start_pc}                     0x2000
3${trap_address}                 0x4000
4
5${unimp_op}                     0xC0001073 # CSRRW 0x, cycle, x0. Since cycle is read only, triggers illegal instruction exception
6${mret}                         0x30200073 # mret
7
8${user_level}                   0b0
9${machine_level}                0b11
10
11*** Keywords ***
12Create Machine
13    [Arguments]                 ${bitness}      ${privilege}
14    Execute Command             using sysbus
15    Execute Command             mach create "risc-v"
16
17    Execute Command             machine LoadPlatformDescriptionFromString "clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 { frequency: 66000000 }"
18    Execute Command             machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV${bitness} @ sysbus { timeProvider: clint; cpuType: \\"rv${bitness}gc\\"; privilegeLevels: ${privilege}; interruptMode: 1 }"
19    Execute Command             machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x1000 { size: 0x40000 }"
20
21    Execute Command             cpu PC ${start_pc}
22
23    Execute Command             cpu MTVEC ${trap_address}
24
25    Execute Command             sysbus WriteDoubleWord ${start_pc} ${unimp_op}
26    Execute Command             sysbus WriteDoubleWord ${trap_address} ${mret}
27
28MPP Should Equal
29    [Arguments]                 ${expected}
30    ${mstatus}=                 Execute Command             cpu MSTATUS
31    ${mpp}=                     Evaluate                    (${mstatus.strip()} & (0b11 << 11)) >> 11
32    Should Be Equal As numbers  ${mpp}      ${expected}
33
34Test Mret
35    [Arguments]                 ${lowest_priv_level}
36    Execute Command             cpu Step
37
38    MPP Should Equal            0b11    # Machine Level
39
40    ${pc}=                      Execute Command         cpu PC
41    Should Be Equal As Numbers  ${pc}    0x4000
42
43    Execute Command             cpu Step
44
45    ${pc}=                      Execute Command         cpu PC
46    Should Be Equal As Numbers  ${pc}    0x2000
47
48    MPP Should Equal            ${lowest_priv_level}
49
50*** Test Cases ***
51User Level Exists 64Bits
52    Create Machine              bitness=64      privilege=PrivilegeLevels.MachineUser
53    Test Mret                   ${user_level}
54
55User Level Exists 32Bits
56    Create Machine              bitness=32      privilege=PrivilegeLevels.MachineUser
57    Test Mret                   ${user_level}
58
59User Level Does Not Exists 64Bits
60    Create Machine              bitness=64      privilege=PrivilegeLevels.Machine
61    Test Mret                   ${machine_level}
62
63User Level Does Not Exists 32Bits
64    Create Machine              bitness=32      privilege=PrivilegeLevels.Machine
65    Test Mret                   ${machine_level}
66