1*** Variables ***
2${X1}                                           1
3${X2}                                           2
4${X3}                                           3
5
6*** Keywords ***
7Create Machine
8    Execute Command                             using sysbus
9    Execute Command                             mach create
10    Execute Command                             machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV32 @ sysbus { cpuType: \\"rv32imac\\"; timeProvider: empty; allowUnalignedAccesses: true }"
11    Execute Command                             machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x0 { size: 0x10000000 }"
12
13*** Test Cases ***
14Should Invalidate On Write
15    Create Machine
16
17    # li x1, 1
18    Execute Command                             sysbus WriteDoubleWord 0x0 0x00100093
19    # j .
20    Execute Command                             sysbus WriteDoubleWord 0x4 0x0000006f
21
22    Execute Command                             cpu PC 0x0
23    Register Should Be Equal                    ${X1}  0x0
24    Execute Command                             emulation RunFor "0.01"
25
26    PC Should Be Equal                          0x4
27    Register Should Be Equal                    ${X1}  0x1
28
29    # this overwrites the `li` instruction
30    # chaning the immediate value;
31    # if the invalidation works fine, we should
32    # observe the new value in the register
33    # after running the code for the second time
34
35    # li x1, 2
36    Execute Command                             sysbus WriteDoubleWord 0x0 0x00200093
37
38    Execute Command                             cpu PC 0x0
39    Execute Command                             cpu SetRegister ${X1} 0x0
40    Execute Command                             emulation RunFor "0.01"
41
42    PC Should Be Equal                          0x4
43    Register Should Be Equal                    ${X1}  0x2
44
45Should Invalidate on Cross Page Word Write
46    Create Machine
47
48    # we use this particular PC as it's at the
49    # edge of memory segments
50    Execute Command                             cpu PC 0xfffffc
51
52    # li x1, 1
53    Execute Command                             sysbus WriteDoubleWord 0xfffffc 0x00100093
54
55    # li x2, 1
56    Execute Command                             sysbus WriteDoubleWord 0x1000000 0x00100113
57
58    # j .
59    Execute Command                             sysbus WriteDoubleWord 0x1000004 0x0000006f
60
61    Execute Command                             cpu PC 0xfffffc
62    Register Should Be Equal                    ${X1}  0x0
63    Register Should Be Equal                    ${X2}  0x0
64    Register Should Be Equal                    ${X3}  0x0
65    Execute Command                             emulation RunFor "0.0001"
66
67    PC Should Be Equal                          0x1000004
68    Register Should Be Equal                    ${X1}  0x1
69    Register Should Be Equal                    ${X2}  0x1
70    Register Should Be Equal                    ${X3}  0x0
71
72    # this single write modifies both `li` commands
73    # so that the first one writes 0x131 instead of 0x1
74    # and the second one writes to X2 instead of X1;
75    # if the invalidation works fine, we should
76    # observe new values in registers
77    # after running the code for the second time
78    Execute Command                             sysbus WriteWord 0xffffff 0x9313
79
80    Execute Command                             cpu PC 0xfffffc
81    Execute Command                             cpu SetRegister ${X1} 0x0
82    Execute Command                             cpu SetRegister ${X2} 0x0
83    Execute Command                             cpu SetRegister ${X3} 0x0
84    Execute Command                             emulation RunFor "0.0001"
85
86    PC Should Be Equal                          0x1000004
87    Register Should Be Equal                    ${X1}  0x131
88    Register Should Be Equal                    ${X2}  0x0
89    Register Should Be Equal                    ${X3}  0x1
90
91Should Invalidate on Cross Page DoubleWord Write
92    Create Machine
93
94    # we use this particular PC as it's at the
95    # edge of memory segments
96    Execute Command                             cpu PC 0xfffffc
97
98    # li x1, 1
99    Execute Command                             sysbus WriteDoubleWord 0xfffffc 0x00100093
100
101    # li x2, 1
102    Execute Command                             sysbus WriteDoubleWord 0x1000000 0x00100113
103
104    # j .
105    Execute Command                             sysbus WriteDoubleWord 0x1000004 0x0000006f
106
107    Execute Command                             cpu PC 0xfffffc
108    Register Should Be Equal                    ${X1}  0x0
109    Register Should Be Equal                    ${X2}  0x0
110    Register Should Be Equal                    ${X3}  0x0
111    Execute Command                             emulation RunFor "0.0001"
112
113    PC Should Be Equal                          0x1000004
114    Register Should Be Equal                    ${X1}  0x1
115    Register Should Be Equal                    ${X2}  0x1
116    Register Should Be Equal                    ${X3}  0x0
117
118    # this single write modifies both `li` commands
119    # so that the first one writes 0x131 instead of 0x1
120    # and the second one writes to X2 instead of X1;
121    # if the invalidation works fine, we should
122    # observe new values in registers
123    # after running the code for the second time
124    Execute Command                             sysbus WriteDoubleWord 0xfffffe 0x01931310
125
126    Execute Command                             cpu PC 0xfffffc
127    Execute Command                             cpu SetRegister ${X1} 0x0
128    Execute Command                             cpu SetRegister ${X2} 0x0
129    Execute Command                             cpu SetRegister ${X3} 0x0
130    Execute Command                             emulation RunFor "0.0001"
131
132    PC Should Be Equal                          0x1000004
133    Register Should Be Equal                    ${X1}  0x131
134    Register Should Be Equal                    ${X2}  0x0
135    Register Should Be Equal                    ${X3}  0x1
136
137