1*** Variables ***
2${starting_pc}                      0x1000
3${pc_in_loop}                       0x1004
4${emulation_time}                   "0.00002"
5
6# Platform definitions
7${PLAT_ARM64}                       SEPARATOR=\n  """
8...                                 cpu: CPU.ARMv8R @ sysbus
9...                                 ${SPACE*4}cpuType: "cortex-r52"
10...                                 ${SPACE*4}genericInterruptController: gic
11...
12...                                 gic: IRQControllers.ARM_GenericInterruptController
13...                                 """
14${PLAT_ARM-M}                       SEPARATOR=\n  """
15...                                 cpu: CPU.CortexM @ sysbus
16...                                 ${SPACE*4}cpuType: "cortex-m7"
17...                                 ${SPACE*4}nvic: nvic
18...
19...                                 nvic: IRQControllers.NVIC
20...                                 """
21${PLAT_X86}                         SEPARATOR=\n  """
22...                                 cpu: CPU.X86 @ sysbus
23...                                 ${SPACE*4}cpuType: "x86"
24...                                 ${SPACE*4}lapic: lapic
25...
26...                                 lapic: IRQControllers.LAPIC @ sysbus 0xFEE00000
27...                                 """
28${PLAT_SPARC}                       "cpu: CPU.Sparc @ sysbus { cpuType: \\"leon3\\" }"
29${PLAT_POWERPC}                     "cpu: CPU.PowerPc @ sysbus { cpuType: \\"e200z6\\" }"
30${PLAT_ARM}                         'cpu: CPU.ARMv7R @ sysbus { cpuType: "cortex-r8"}'
31${PLAT_RISCV}                       'cpu: CPU.RiscV32 @ sysbus { cpuType: "rv32i"}'
32${PLAT_XTENSA}                      'cpu: CPU.Xtensa @ sysbus { cpuType: "sample_controller"}'
33
34# Test programs for each architecture
35${PROG_RISCV}                       SEPARATOR=\n
36...                                 loop:
37...                                 nop
38...                                 nop
39...                                 nop
40...                                 jal loop
41${PROG_ARM}                         SEPARATOR=\n
42...                                 loop:
43...                                 nop
44...                                 nop
45...                                 nop
46...                                 b loop
47${PROG_X86}                         SEPARATOR=\n
48...                                 loop:
49...                                 nop
50...                                 nop
51...                                 nop
52...                                 nop
53...                                 jmp loop
54${PROG_SPARC}                       SEPARATOR=\n
55...                                 loop:
56...                                 nop
57...                                 nop
58...                                 nop
59...                                 nop
60...                                 bg loop
61...                                 nop
62${PROG_POWERPC}                     SEPARATOR=\n
63...                                 loop:
64...                                 nop
65...                                 nop
66...                                 nop
67...                                 nop
68...                                 b loop
69
70*** Keywords ***
71Create Machine
72    [Arguments]                     ${PLAT}  ${PROG}
73    Execute Command                 using sysbus
74    Execute Command                 mach create
75    Execute Command                 machine LoadPlatformDescriptionFromString ${PLAT}
76    Configure Machine
77    Execute Command                 sysbus.cpu AssembleBlock ${starting_pc} "${PROG}"
78
79Create Machine Xtensa
80    Execute Command                 using sysbus
81    Execute Command                 mach create
82    Execute Command                 machine LoadPlatformDescriptionFromString ${PLAT_XTENSA}
83    Configure Machine
84
85    # renode-llvm-disas doesnt support Xtensa yet so the program has to be written directly to memory
86
87    #  nops
88    Execute Command                 sysbus WriteWord 0x1000 0xF03D
89    Execute Command                 sysbus WriteWord 0x1002 0xF03D
90    Execute Command                 sysbus WriteWord 0x1004 0xF03D
91    Execute Command                 sysbus WriteWord 0x1006 0xF03D
92    Execute Command                 sysbus WriteWord 0x1008 0xF03D
93    Execute Command                 sysbus WriteWord 0x100a 0xF03D
94    #  jmp back to 0x1000
95    Execute Command                 sysbus WriteDoubleWord 0x100c 0x00FFFC06
96
97Configure Machine
98    Execute Command                 machine LoadPlatformDescriptionFromString 'mem: Memory.MappedMemory @ sysbus 0x1000 { size: 0x1000000 }'
99
100    Execute Command                 cpu PerformanceInMips 1
101
102    # Needed to check PC between the blocks on a hook
103    Execute Command                 cpu MaximumBlockSize 1
104    Execute Command                 cpu SetHookAtBlockBegin "self.DebugLog('block started: ' + 'PC '+ str(self.PC))"
105
106    Create Log Tester               0.01  defaultPauseEmulation=true
107    Execute Command                 logLevel -1
108
109Syncing Enabled Template
110    [Arguments]                     ${PLAT}  ${PROG}
111    Create Machine                  ${PLAT}  ${PROG}
112    Test SyncPCEveryInstructionDisabled False
113
114Syncing Disabled Template
115    [Arguments]                     ${PLAT}  ${PROG}
116    Create Machine                  ${PLAT}  ${PROG}
117    Test SyncPCEveryInstructionDisabled True
118
119# Tests run a loop of nops, after first loop translation blocks should be chained, then a hook can verify that the PC is updated between the blocks
120
121Test SyncPCEveryInstructionDisabled True
122    Execute Command                 cpu PC ${starting_pc}
123    Execute Command                 cpu SyncPCEveryInstructionDisabled true
124    Execute Command                 emulation RunFor ${emulation_time}
125
126    # wait for first loop
127    Wait For Log Entry              block started: PC ${pc_in_loop}  timeout=0
128
129    # after chaining we should expect wrong PC
130    Run Keyword And Expect Error
131    ...                             *KeywordException: Expected pattern "block started: PC ${pc_in_loop}" did not appear in the log*
132    ...                             Wait For Log Entry  block started: PC ${pc_in_loop}  timeout=0
133
134# This test checks for an unwanted behavior
135
136Test SyncPCEveryInstructionDisabled False
137    Execute Command                 cpu PC ${starting_pc}
138    Execute Command                 cpu SyncPCEveryInstructionDisabled false
139    Execute Command                 emulation RunFor ${emulation_time}
140
141    # wait for first loop
142    Wait For Log Entry              block started: PC ${pc_in_loop}  timeout=0
143
144    # after chaining we still expect PC from inside loop
145    Wait For Log Entry              block started: PC ${pc_in_loop}  timeout=0
146
147*** Test Cases ***
148Should Report Wrong PC Between Chained Blocks
149    [Template]                      Syncing Disabled Template
150    ${PLAT_ARM}                     ${PROG_ARM}
151    ${PLAT_ARM64}                   ${PROG_ARM}
152    ${PLAT_ARM-M}                   ${PROG_ARM}
153    ${PLAT_POWERPC}                 ${PROG_POWERPC}
154    ${PLAT_SPARC}                   ${PROG_SPARC}
155    # PC is already updated between instructions for RISC-V, Xtensa and X86
156
157Should Report Correct PC Between Chained Blocks
158    [Template]                      Syncing Enabled Template
159    ${PLAT_RISCV}                   ${PROG_RISCV}
160    ${PLAT_ARM}                     ${PROG_ARM}
161    ${PLAT_ARM64}                   ${PROG_ARM}
162    ${PLAT_ARM-M}                   ${PROG_ARM}
163    ${PLAT_POWERPC}                 ${PROG_POWERPC}
164    ${PLAT_X86}                     ${PROG_X86}
165    ${PLAT_SPARC}                   ${PROG_SPARC}
166
167# Separate path for Xtensa as it's currently not supported by Renode's LLVM assembly
168Should Report Correct PC Between Chained Blocks Xtensa
169    Create Machine Xtensa
170    Test SyncPCEveryInstructionDisabled False
171