1*** Keywords ***
2Prepare Machine
3    [Arguments]  ${architecture}  ${memoryType}
4
5    Execute Command           using sysbus
6    Execute Command           mach create "Leon3"
7
8    Execute Command           machine LoadPlatformDescriptionFromString "sysbus: { Endianess: Endianess.BigEndian }"
9    IF  "${architecture}" == "Sparc"
10        Execute Command       machine LoadPlatformDescriptionFromString "cpu: CPU.Sparc @ sysbus { cpuType: \\"leon3\\" }"
11    ELSE IF  "${architecture}" == "PowerPC"
12        Execute Command       machine LoadPlatformDescriptionFromString "cpu: CPU.PowerPc @ sysbus { cpuType: \\"e200z6\\" }"
13    ELSE
14        Fail                  Unknown architecture ${architecture}
15    END
16    Execute Command           machine LoadPlatformDescriptionFromString "rom: Memory.MappedMemory @ sysbus 0x0 { size: 0x40000000 }"
17    Execute Command           machine LoadPlatformDescriptionFromString "ddr: Memory.${memoryType} @ sysbus 0x40000000 { size: 0x20000000 }"
18
19    Execute Command           cpu PC 0x0
20
21Load Sparc Reader Program
22    # Note that these writes to memory are in the emulation target's endianness (which is big-endian here), NOT the host's.
23    # For example, after `sysbus WriteDoubleWord 0x00000000 0x03100000`, the memory content as a byte array is `[0x03, 0x10, 0x00, 0x00]`.
24    # sethi  %hi(0x40000000), %g1
25    Execute Command           sysbus WriteDoubleWord 0x00000000 0x03100000
26    # or     %g1, 0x104, %g1
27    Execute Command           sysbus WriteDoubleWord 0x00000004 0x82106104
28    # ld     [ %g1 ], %g2
29    Execute Command           sysbus WriteDoubleWord 0x00000008 0xc4004000
30    # b      .
31    Execute Command           sysbus WriteDoubleWord 0x0000000c 0x10800000
32    # nop
33    Execute Command           sysbus WriteDoubleWord 0x00000010 0x01000000
34
35Load Sparc Writer Program
36    # sethi  %hi(0x40000000), %g1
37    Execute Command           sysbus WriteDoubleWord 0x00000000 0x03100000
38    # or  %g1, 0x104, %g1
39    Execute Command           sysbus WriteDoubleWord 0x00000004 0x82106104
40    # sethi  %hi(0x12345400), %g2
41    Execute Command           sysbus WriteDoubleWord 0x00000008 0x05048d15
42    # or  %g2, 0x278, %g2
43    Execute Command           sysbus WriteDoubleWord 0x0000000c 0x8410a278
44    # st  %g2, [ %g1 ]
45    Execute Command           sysbus WriteDoubleWord 0x00000010 0xc4204000
46    # b .-4  # We jump back to the st instruction to be able to test watchpoints multiple times
47    Execute Command           sysbus WriteDoubleWord 0x00000014 0x10bfffff
48    # nop
49    Execute Command           sysbus WriteDoubleWord 0x00000018 0x01000000
50
51Load PowerPC Reader Program
52    # lis r1, 0x4000
53    Execute Command           sysbus WriteDoubleWord 0x00000000 0x3c204000
54    # ori r1, r1, 0x104
55    Execute Command           sysbus WriteDoubleWord 0x00000004 0x60210104
56    # lwz r2, 0(r1)
57    Execute Command           sysbus WriteDoubleWord 0x00000008 0x80410000
58    # b .
59    Execute Command           sysbus WriteDoubleWord 0x0000000c 0x48000000
60    # nop
61    Execute Command           sysbus WriteDoubleWord 0x00000010 0x60000000
62
63Load PowerPC Writer Program
64    # lis r1, 0x4000
65    Execute Command           sysbus WriteDoubleWord 0x00000000 0x3c204000
66    # ori r1, r1, 0x104
67    Execute Command           sysbus WriteDoubleWord 0x00000004 0x60210104
68    # lis r2, 0x1234
69    Execute Command           sysbus WriteDoubleWord 0x00000008 0x3c401234
70    # ori r2, r2, 0x5678
71    Execute Command           sysbus WriteDoubleWord 0x0000000c 0x60425678
72    # stw r2, 0(r1)
73    Execute Command           sysbus WriteDoubleWord 0x00000010 0x90410000
74    # b .-4
75    Execute Command           sysbus WriteDoubleWord 0x00000014 0x4bfffffc
76    # nop
77    Execute Command           sysbus WriteDoubleWord 0x00000018 0x60000000
78
79Load Program
80    [Arguments]  ${architecture}  ${type}
81
82    Run Keyword               Load ${architecture} ${type} Program
83
84Memory Should Be Equal
85    [Arguments]  ${address}   ${value}  ${width}=DoubleWord
86    ${res}=  Execute Command  sysbus Read${width} ${address}
87    Should Be Equal As Numbers  ${res}  ${value}
88
89Should Read Big-Endian Value With Watchpoint
90    [Arguments]  ${architecture}  ${memoryType}
91
92    Prepare Machine           ${architecture}  ${memoryType}
93    Load Program              ${architecture}  Reader
94
95    # Target-endian write
96    Execute Command           sysbus WriteDoubleWord 0x40000104 0x12345678
97
98    # Same page as the value that gets accessed, not same address
99    Execute Command           sysbus AddWatchpointHook 0x40000200 4 2 "pass"
100
101    PC Should Be Equal        0x00000000
102
103    Execute Command           cpu Step 3
104    PC Should Be Equal        0x0000000c
105    Register Should Be Equal  2  0x12345678
106
107Should Write Big-Endian Value With Watchpoint
108    [Arguments]  ${architecture}  ${memoryType}
109
110    Prepare Machine           ${architecture}  ${memoryType}
111    Load Program              ${architecture}  Writer
112
113    # Same page as the value that gets accessed, not same address
114    Execute Command           sysbus AddWatchpointHook 0x40000200 4 2 "pass"
115
116    PC Should Be Equal        0x00000000
117    Memory Should Be Equal    0x40000104  0x00000000
118
119    Execute Command           cpu Step 5
120    PC Should Be Equal        0x00000014
121    Memory Should Be Equal    0x40000104  0x12345678
122    # Also verify that reading parts of the value separately works as expected
123    Memory Should Be Equal    0x40000104  0x1234  Word
124    Memory Should Be Equal    0x40000106  0x5678  Word
125    Memory Should Be Equal    0x40000104  0x12  Byte
126
127Write Watchpoint Should See Correct Value
128    [Arguments]  ${architecture}  ${memoryType}
129
130    Prepare Machine           ${architecture}  ${memoryType}
131    Create Log Tester         0
132    Load Program              ${architecture}  Writer
133
134    # Watch the address that gets accessed
135    # Watchpoints see the value as the CPU sees it, so BE here.
136    Execute Command           sysbus AddWatchpointHook 0x40000104 4 2 "self.DebugLog('Watchpoint saw ' + hex(value))"
137    Execute Command           logLevel 0
138
139    PC Should Be Equal        0x00000000
140    Memory Should Be Equal    0x40000104  0x00000000
141
142    Execute Command           cpu Step 6
143    IF  "${architecture}" == "Sparc"
144        PC Should Be Equal    0x00000018
145    ELSE
146        PC Should Be Equal    0x00000010
147    END
148    Wait For Log Entry        Watchpoint saw 0x12345678L
149
150Write Watchpoint Should Work Multiple Times
151    [Arguments]  ${architecture}  ${memoryType}
152
153    Prepare Machine           ${architecture}  ${memoryType}
154    Create Log Tester         0
155    Load Program              ${architecture}  Writer
156
157    # Watch the address that gets accessed
158    Execute Command           sysbus AddWatchpointHook 0x40000104 4 2 "self.DebugLog('Watchpoint saw ' + hex(value))"
159    Execute Command           logLevel 0
160
161    PC Should Be Equal        0x00000000
162    Memory Should Be Equal    0x40000104  0x00000000
163
164    Execute Command           cpu ExecutionMode Continuous
165    Execute Command           start
166
167    FOR    ${i}    IN RANGE    32
168        Wait For Log Entry        Watchpoint saw 0x12345678L    timeout=1
169    END
170
171Abort Should Work After Watchpoint Hit
172    [Arguments]  ${memoryType}
173
174    Prepare Machine           Sparc  ${memoryType}
175    Create Log Tester         0
176    Load Program              Sparc  Writer
177
178    # Overwrite branch with illegal instruction
179    Execute Command           rom WriteDoubleWord 0x00000014 0xffffffff
180
181    # Watch the address that gets accessed
182    Execute Command           sysbus AddWatchpointHook 0x40000104 4 2 "self.DebugLog('Watchpoint saw ' + hex(value))"
183    Execute Command           logLevel 0
184
185    PC Should Be Equal        0x00000000
186    Memory Should Be Equal    0x40000104  0x00000000
187
188    Execute Command           cpu ExecutionMode Continuous
189    Execute Command           start
190
191    Wait For Log Entry        Watchpoint saw 0x12345678L    timeout=1
192    Wait For Log Entry        CPU abort [PC=0x14]: Trap 0x02 while interrupts disabled    timeout=1
193
194Should Read Big-Endian Value Without Watchpoint
195    [Arguments]  ${architecture}
196
197    Prepare Machine           ${architecture}  MappedMemory
198    Load Program              ${architecture}  Reader
199
200    # Target-endian write
201    Execute Command           sysbus WriteDoubleWord 0x40000104 0x12345678
202
203    PC Should Be Equal        0x00000000
204
205    Execute Command           cpu Step 3
206    PC Should Be Equal        0x0000000c
207    Register Should Be Equal  2  0x12345678
208
209Should Write Big-Endian Value Without Watchpoint
210    [Arguments]  ${architecture}
211
212    Prepare Machine           ${architecture}  MappedMemory
213    Load Program              ${architecture}  Writer
214
215    PC Should Be Equal        0x00000000
216    Memory Should Be Equal    0x40000104  0x00000000
217
218    Execute Command           cpu Step 5
219    PC Should Be Equal        0x00000014
220    Memory Should Be Equal    0x40000104  0x12345678
221
222
223*** Test Cases ***
224Should Read Big-Endian Value Without Watchpoint On Sparc
225    Should Read Big-Endian Value Without Watchpoint  Sparc
226
227Should Write Big-Endian Value Without Watchpoint On Sparc
228    Should Write Big-Endian Value Without Watchpoint  Sparc
229
230Should Read Big-Endian Value With Watchpoint On MappedMemory On Sparc
231    Should Read Big-Endian Value With Watchpoint  Sparc  MappedMemory
232
233Should Read Big-Endian Value With Watchpoint On ArrayMemory On Sparc
234    Should Read Big-Endian Value With Watchpoint  Sparc  ArrayMemory
235
236Should Write Big-Endian Value With Watchpoint On MappedMemory On Sparc
237    Should Write Big-Endian Value With Watchpoint  Sparc  MappedMemory
238
239Should Write Big-Endian Value With Watchpoint On ArrayMemory On Sparc
240    Should Write Big-Endian Value With Watchpoint  Sparc  ArrayMemory
241
242Write Watchpoint Should See Correct Value On MappedMemory On Sparc
243    Write Watchpoint Should See Correct Value  Sparc  MappedMemory
244
245Write Watchpoint Should See Correct Value On ArrayMemory On Sparc
246    Write Watchpoint Should See Correct Value  Sparc  ArrayMemory
247
248Write Watchpoint Should Work Multiple Times On MappedMemory On Sparc
249    Write Watchpoint Should Work Multiple Times  Sparc  MappedMemory
250
251Write Watchpoint Should Work Multiple Times On ArrayMemory On Sparc
252    Write Watchpoint Should Work Multiple Times  Sparc  ArrayMemory
253
254Should Read Big-Endian Value With Watchpoint On MappedMemory On PowerPC
255    Should Read Big-Endian Value With Watchpoint  PowerPC  MappedMemory
256
257Should Read Big-Endian Value With Watchpoint On ArrayMemory On PowerPC
258    Should Read Big-Endian Value With Watchpoint  PowerPC  ArrayMemory
259
260Should Write Big-Endian Value With Watchpoint On MappedMemory On PowerPC
261    Should Write Big-Endian Value With Watchpoint  PowerPC  MappedMemory
262
263Should Write Big-Endian Value With Watchpoint On ArrayMemory On PowerPC
264    Should Write Big-Endian Value With Watchpoint  PowerPC  ArrayMemory
265
266Write Watchpoint Should See Correct Value On MappedMemory On PowerPC
267    Write Watchpoint Should See Correct Value  PowerPC  MappedMemory
268
269Write Watchpoint Should See Correct Value On ArrayMemory On PowerPC
270    Write Watchpoint Should See Correct Value  PowerPC  ArrayMemory
271
272Write Watchpoint Should Work Multiple Times On MappedMemory On PowerPC
273    Write Watchpoint Should Work Multiple Times  PowerPC  MappedMemory
274
275Write Watchpoint Should Work Multiple Times On ArrayMemory On PowerPC
276    Write Watchpoint Should Work Multiple Times  PowerPC  ArrayMemory
277
278Abort Should Work After Watchpoint Hit On MappedMemory
279    Abort Should Work After Watchpoint Hit  MappedMemory
280
281Abort Should Work After Watchpoint Hit On ArrayMemory
282    Abort Should Work After Watchpoint Hit  ArrayMemory
283
284Watchpoint Should Not Affect Execution On MPC5567
285    # This is a big-endian PowerPC platform
286    Execute Script            ${CURDIR}/../../scripts/single-node/mpc5567.resc
287    Create Terminal Tester    sysbus.uart
288    Create Log Tester         0
289    # This address has been chosen to cause a failure to boot if the presence of the watchpoint
290    # causes an access endianness mismatch
291    Execute Command           sysbus AddWatchpointHook 0x40002ccc 4 3 "cpu.WarningLog('Watchpoint hit')"
292
293    Wait For Prompt On Uart   QR5567>  pauseEmulation=true
294    Wait For Log Entry        Watchpoint hit
295    # Ensure that access translation works as expected for big-endian peripherals by reading the
296    # UART status register, because the MPC5567_UART has ByteToDoubleWord
297    Memory Should Be Equal    0xfffb0008  0xc0000000
298    Memory Should Be Equal    0xfffb0008  0xc0  Byte
299    Memory Should Be Equal    0xfffb0009  0x00  Byte
300    Memory Should Be Equal    0xfffb000a  0x00  Byte
301    Memory Should Be Equal    0xfffb000b  0x00  Byte
302
303Watchpoint Should Not Affect Execution On Microwatt
304    # This is a little-endian PowerPC platform
305    Execute Script            ${CURDIR}/../../scripts/single-node/microwatt.resc
306    Create Terminal Tester    sysbus.uart
307    Create Log Tester         0
308    # This address has been chosen to cause a failure to boot if the presence of the watchpoint
309    # causes an access endianness mismatch
310    Execute Command           sysbus AddWatchpointHook 0x5fee0 8 3 "cpu.WarningLog('Watchpoint hit')"
311
312    Wait For Prompt On Uart   >>>  pauseEmulation=true
313    Wait For Log Entry        Watchpoint hit
314