1*** Variables ***
2# RISC-V registers
3${a0}                         0xa
4${a1}                         0xb
5${a2}                         0xc
6${a3}                         0xd
7
8*** Keywords ***
9Create Machine
10    Execute Command        mach create
11    Execute Command        machine LoadPlatformDescription @platforms/cpus/litex_ibex.repl
12    Execute Command        using sysbus
13
14    Execute Command        cpu PC 0x0
15    Execute Command        sysbus WriteDoubleWord 0x0 0x800593  # 0x0000: li a1, 0x8
16    Execute Command        sysbus WriteDoubleWord 0x4 0x13      # 0x0004: nop
17    Execute Command        sysbus WriteDoubleWord 0x8 0x500e7   # 0x0008: jalr a0
18    Execute Command        sysbus WriteDoubleWord 0xC 0x58067   # 0x000C: jr a1
19
20# Different page
21    Execute Command        sysbus WriteDoubleWord 0x1000 0x13   # 0x1000: nop
22    Execute Command        sysbus WriteDoubleWord 0x1004 0x8067 # 0x1004: ret
23# Same page
24    Execute Command        sysbus WriteDoubleWord 0x10 0x13     # 0x10: nop
25    Execute Command        sysbus WriteDoubleWord 0x14 0x8067   # 0x14: ret
26
27Overwrite With Nops
28    [Arguments]     ${addr}    ${count}
29    FOR  ${offset}  IN RANGE  ${count}
30        Execute Command       sysbus WriteDoubleWord ${addr} 0x13
31        ${addr}=              Evaluate   ${addr} + 4
32    END
33
34Overwrite With Nops As Guest
35# Must be called right before the jump `jalr a0`
36    [Arguments]            ${addr}  ${count}
37    ${ptr}=                Set Variable  0x2000
38    ${tmp_ptr}=            Set Variable  ${ptr}
39    ${prev_a0_value}=      Execute Command  sysbus.cpu GetRegister ${a0}
40    Execute Command        sysbus.cpu SetRegister ${a0} ${ptr}
41    Execute Command        sysbus.cpu SetRegister ${a2} 0x13
42    Execute Command        sysbus.cpu SetRegister ${a3} ${addr}
43
44    # Write instructions overwriting requested range
45    FOR  ${repetition}  IN RANGE  ${count}
46        Execute Command       sysbus WriteDoubleWord ${tmp_ptr} 0x6a123   # 0x20xx: sw x0, 2(a3)
47        ${tmp_ptr}=           Evaluate   ${tmp_ptr} + 4
48        Execute Command       sysbus WriteDoubleWord ${tmp_ptr} 0xc6a023  # 0x20xx: sw a2, 0(a3)
49        ${tmp_ptr}=           Evaluate   ${tmp_ptr} + 4
50        Execute Command       sysbus WriteDoubleWord ${tmp_ptr} 0x468693  # 0x20xx: addi a3, a3, 4
51        ${tmp_ptr}=           Evaluate   ${tmp_ptr} + 4
52    END
53    Execute Command        sysbus WriteDoubleWord ${tmp_ptr} 0x8067  # ret
54
55    # Execute them
56    ${insn_to_exec}=       Evaluate   ${count} * 3 + 3
57    Execute Command        sysbus.cpu Step ${insn_to_exec}
58
59    # Assert the write was succesfull
60    ${insn_at_addr}=       Execute Command  sysbus ReadDoubleWord ${addr}
61    Should Be Equal As Integers  ${insn_at_addr}  0x13
62
63    # Restore significant registers
64    Execute Command     sysbus.cpu SetRegister ${a0} ${prev_a0_value}
65
66Assert PC Equals
67    [Arguments]            ${expected}
68    ${pc}=                 Execute Command  cpu PC
69    Should Be Equal As Integers  ${pc}  ${expected}
70
71*** Test Cases ***
72Shoud Invalidate Other Page When Overwritten Using Sysbus
73    Create Machine
74    Execute Command        sysbus.cpu SetRegister ${a0} 0x1000
75
76    Execute Command        cpu Step 3
77    Assert PC Equals       0x1000
78    Execute Command        cpu Step 3
79    Assert PC Equals       0x08
80
81    Overwrite With Nops    0x1004  2
82
83    Execute Command        cpu Step 3
84    Assert PC Equals       0x1008
85
86Shoud Invalidate The Same Page When Overwritten Using Sysbus
87    Create Machine
88    Execute Command        sysbus.cpu SetRegister ${a0} 0x10
89
90    Execute Command        cpu Step 3
91    Assert PC Equals       0x10
92    Execute Command        cpu Step 3
93    Assert PC Equals       0x08
94
95    Overwrite With Nops    0x14  3
96
97    Execute Command        cpu Step 3
98    Assert PC Equals       0x18
99
100Should Invalidate Other Page When Overwritten By Guest
101    Create Machine
102    Execute Command        sysbus.cpu SetRegister ${a0} 0x1000
103
104    Execute Command        cpu Step 3
105    Assert PC Equals       0x1000
106    Execute Command        cpu Step 3
107    Assert PC Equals       0x8
108
109    Overwrite With Nops As Guest   0x1004  2
110
111    Execute Command        cpu Step 3
112    Assert PC Equals       0x1008
113
114Should Invalidate The Same Page When Overwritten By Guest
115    Create Machine
116    Execute Command        sysbus.cpu SetRegister ${a0} 0x10
117
118    Execute Command        cpu Step 3
119    Assert PC Equals       0x10
120    Execute Command        cpu Step 3
121    Assert PC Equals       0x8
122
123    Overwrite With Nops As Guest   0x14  2
124
125    Execute Command        cpu Step 3
126    Assert PC Equals       0x18
127
128