1*** Variables ***
2${UART}                           sysbus.uart0
3${URI}                            @https://dl.antmicro.com/projects/renode
4
5${ZEPHYR_HELLO_WORLD_ELF}         ${URI}/cortex_a53-zephyr-hello_world.elf-s_34096-272b1e50f90c8240d875daf679223f2d769e77dd
6${ZEPHYR_SYNCHRONIZATION_ELF}     ${URI}/virt-a53--zephyr-synchronization.elf-s_582816-bb556dc10df7f09918db3c5d1f298cdd3f3290f3
7${ZEPHYR_PHILOSOPHERS_ELF}        ${URI}/zephyr_philosophers_a53.elf-s_731440-e6e5bd1c2151b7e5d38d272b01108493e8ef88b4
8${ZEPHYR_FPU_SHARING_ELF}         ${URI}/zephyr_tests_kernel_fpu_sharing_generic_qemu_cortex_a53.elf-s_763936-8839da556c9913ed1817fc213a79c60de8f0d8e2
9
10${SEL4_ADDER_ELF}                 ${URI}/camkes_adder_elfloader_aarch64-s_3408064-4385f32dd7a3235af3905c0a473598fc90853b7a
11
12*** Keywords ***
13Create Machine
14    [Arguments]    ${gic_version}=3
15
16    Execute Command               using sysbus
17    Execute Command               mach create
18    Execute Command               machine LoadPlatformDescription @platforms/cpus/cortex-a53-gicv${gic_version}.repl
19
20    Create Terminal Tester        ${UART}  defaultPauseEmulation=True
21    Execute Command               showAnalyzer ${UART}
22
23Step And Verify Accumulator
24    [Arguments]    ${expected_value}
25
26    Execute Command               cpu Step
27    ${acc} =  Execute Command     cpu GetRegister 0
28    Should Be Equal As Integers   ${acc}  ${expected_value}  base=16
29
30Verify System Registers
31    [Arguments]    ${names}  ${expected_values}
32
33    ${names_length} =   Get Length    ${names}
34    ${values_length} =  Get Length    ${expected_values}
35    Should Be Equal  ${names_length}  ${values_length}
36
37    ${all_values} =  Execute Command    cpu GetAllSystemRegisterValues
38    FOR    ${index}    IN RANGE  ${names_length}
39        ${name} =  Set Variable  ${names[${index}]}
40        ${expected_value} =  Set Variable  ${expected_values[${index}]}
41
42        ${match} =  Get Regexp Matches  ${all_values}  ${name}.*(0x[0-9A-F]+)  1  flags=MULTILINE
43        IF  ${match}
44            Should Be Equal    ${match[0]}    ${expected_value}
45            ...  msg="Invalid value of '${name}' system register: ${match[0]}; expected: ${expected_value}"
46        ELSE
47            Fail  "${name} not found in the system registers list: ${all_values}"
48        END
49    END
50
51Verify Timer Register
52    [Arguments]    ${system_register_name}    ${timer_register_name}
53
54    Execute Command               cpu GetSystemRegisterValue "${system_register_name}"
55    Wait For Log Entry            Read from ${timer_register_name}
56
57*** Test Cases ***
58Should Get Correct EL and SS on CPU Creation
59    # This platform uses `Cortex-A53` CPU - ARMv8A
60    # We only check if EL and SS are reflected correctly on C# side, for their usage in peripherals
61    Create Machine
62
63    ${ss}=                             Execute Command  sysbus.cpu SecurityState
64    ${el}=                             Execute Command  sysbus.cpu ExceptionLevel
65
66    Should Be Equal As Strings         ${ss.split()[0].strip()}  Secure
67    Should Be Equal As Strings         ${el.split()[0].strip()}  EL3_MonitorMode
68
69Test Accessing ARM Generic Timer Registers Through AArch64 System Registers
70    Create Machine
71    Create Log Tester             0
72    Execute Command               logLevel 0 cpu.timer
73
74    # Read logs for '*Count' registers are disabled by default because they tend to be read very often.
75    Execute Command               cpu.timer EnableCountReadLogs true
76
77    # AArch64 system register reads go through tlib and are handled by ARM Generic Timer which prints a DEBUG access log.
78    # The log line is used to verify that a proper peripheral register is connected to the given AArch64 system register.
79    Verify Timer Register         CNTFRQ_EL0         Frequency
80    Verify Timer Register         CNTHCTL_EL2        HypervisorControl
81    Verify Timer Register         CNTKCTL_EL1        KernelControl
82
83    Verify Timer Register         CNTPCT_EL0         PhysicalCount
84    Verify Timer Register         CNTPCTSS_EL0       PhysicalSelfSynchronizedCount
85    Verify Timer Register         CNTPOFF_EL2        PhysicalOffset
86
87    Verify Timer Register         CNTVCT_EL0         VirtualCount
88    Verify Timer Register         CNTVCTSS_EL0       VirtualSelfSynchronizedCount
89    Verify Timer Register         CNTVOFF_EL2        VirtualOffset
90
91    Verify Timer Register         CNTHP_CTL_EL2      NonSecureEL2PhysicalTimerControl
92    Verify Timer Register         CNTHP_CVAL_EL2     NonSecureEL2PhysicalTimerCompareValue
93    Verify Timer Register         CNTHP_TVAL_EL2     NonSecureEL2PhysicalTimerValue
94
95    Verify Timer Register         CNTHPS_CTL_EL2     SecureEL2PhysicalTimerControl
96    Verify Timer Register         CNTHPS_CVAL_EL2    SecureEL2PhysicalTimerCompareValue
97    Verify Timer Register         CNTHPS_TVAL_EL2    SecureEL2PhysicalTimerValue
98
99    Verify Timer Register         CNTHV_CTL_EL2      NonSecureEL2VirtualTimerControl
100    Verify Timer Register         CNTHV_CVAL_EL2     NonSecureEL2VirtualTimerCompareValue
101    Verify Timer Register         CNTHV_TVAL_EL2     NonSecureEL2VirtualTimerValue
102
103    Verify Timer Register         CNTHVS_CTL_EL2     SecureEL2VirtualTimerControl
104    Verify Timer Register         CNTHVS_CVAL_EL2    SecureEL2VirtualTimerCompareValue
105    Verify Timer Register         CNTHVS_TVAL_EL2    SecureEL2VirtualTimerValue
106
107    Verify Timer Register         CNTP_CTL_EL0       EL1PhysicalTimerControl
108    Verify Timer Register         CNTP_CVAL_EL0      EL1PhysicalTimerCompareValue
109    Verify Timer Register         CNTP_TVAL_EL0      EL1PhysicalTimerValue
110
111    Verify Timer Register         CNTPS_CTL_EL1      EL3PhysicalTimerControl
112    Verify Timer Register         CNTPS_CVAL_EL1     EL3PhysicalTimerCompareValue
113    Verify Timer Register         CNTPS_TVAL_EL1     EL3PhysicalTimerValue
114
115    Verify Timer Register         CNTV_CTL_EL0       EL1VirtualTimerControl
116    Verify Timer Register         CNTV_CVAL_EL0      EL1VirtualTimerCompareValue
117    Verify Timer Register         CNTV_TVAL_EL0      EL1VirtualTimerValue
118
119Test Accessing System Registers
120    Create Machine
121
122    ${MIDR_val} =         Set Variable  0x410FD034
123    ${new_DAIF} =         Set Variable  0x180
124    ${new_NZCV} =         Set Variable  0xA0000000
125    ${new_SCTLR} =        Set Variable  0xDEADBEEF
126
127    @{register_names} =   Create List   DAIF   MIDR_EL1     NZCV        SCTLR_EL3
128    @{expected_values} =  Create List   0x3C0  ${MIDR_val}  0x40000000  0xC50838
129
130    Verify System Registers       ${register_names}  ${expected_values}
131
132    # MIDR_EL1 is a Read-Only register. Setting it should fail.
133    Run Keyword And Expect Error  KeywordException: *Writing the MIDR_EL1 register isn't supported*
134    ...  Execute Command          cpu SetSystemRegisterValue "MIDR_EL1" 0xDEADBEEF
135
136    Execute Command               cpu SetSystemRegisterValue "DAIF" ${new_DAIF}
137    Execute Command               cpu SetSystemRegisterValue "NZCV" ${new_NZCV}
138    Execute Command               cpu SetSystemRegisterValue "SCTLR_EL3" ${new_SCTLR}
139
140    @{expected_values} =  Create List   ${new_DAIF}  ${MIDR_val}  ${new_NZCV}  ${new_SCTLR}
141    Verify System Registers       ${register_names}  ${expected_values}
142
143Test CRC32X
144    Create Machine
145
146    Execute Command               sysbus WriteDoubleWord 0x0 0x9ac34c00  # crc32x  w0, w0, x3
147    Execute Command               sysbus WriteDoubleWord 0x4 0x9ac44c00  # crc32x  w0, w0, x4
148
149    # Set the initial accumulator value.
150    Execute Command               cpu SetRegisterUlong 0 0xcafebee
151
152    # Set source registers.
153    Execute Command               cpu SetRegisterUlong 3 0x1234567890abcdef
154    Execute Command               cpu SetRegisterUlong 4 0xfedcba0987654321
155
156    # CRC has many caveats with conversions done on input/output/accumulator.
157    # Let's make sure a proper version is used. Mono used to overwrite tlib's
158    # implementation with zlib's crc32 which internally converts accumulator
159    # and output and then the results here are 0x4ab0398 and 0xf77db35e.
160    Step And Verify Accumulator   0x6189dcf1
161    Step And Verify Accumulator   0x1bc6f80b
162
163Test CRC32CX
164    Create Machine
165
166    Execute Command               sysbus WriteDoubleWord 0x0 0x9ac35c00  # crc32cx  w0, w0, x3
167    Execute Command               sysbus WriteDoubleWord 0x4 0x9ac45c00  # crc32cx  w0, w0, x4
168
169    # Set the initial accumulator value.
170    Execute Command               cpu SetRegisterUlong 0 0xcafebee
171
172    # Set source registers.
173    Execute Command               cpu SetRegisterUlong 3 0x1234567890abcdef
174    Execute Command               cpu SetRegisterUlong 4 0xfedcba0987654321
175
176    Step And Verify Accumulator   0x8da20236
177    Step And Verify Accumulator   0xbcfc085a
178
179Test Running the Hello World Zephyr Sample
180    Create Machine
181    Execute Command               sysbus LoadELF ${ZEPHYR_HELLO_WORLD_ELF}
182
183    Wait For Line On Uart         Booting Zephyr OS
184    Provides                      zephyr-hello-world-after-booting
185    Wait For Line On Uart         Hello World!
186
187Test Resuming Zephyr Hello World After Deserialization
188    Requires                      zephyr-hello-world-after-booting
189    Execute Command               showAnalyzer ${UART}
190    Wait For Line On Uart         Hello World!
191
192Test Running the Zephyr Synchronization Sample
193    Create Machine
194    Execute Command               sysbus LoadELF ${ZEPHYR_SYNCHRONIZATION_ELF}
195
196    Wait For Line On Uart         Booting Zephyr OS
197    Wait For Line On Uart         thread_a: Hello World from cpu 0
198    Wait For Line On Uart         thread_b: Hello World from cpu 0
199    Wait For Line On Uart         thread_a: Hello World from cpu 0
200    Wait For Line On Uart         thread_b: Hello World from cpu 0
201
202Test Running the Zephyr Philosophers Sample
203    Create Machine
204    Execute Command               sysbus LoadELF ${ZEPHYR_PHILOSOPHERS_ELF}
205
206    Wait For Line On Uart         Booting Zephyr OS
207    Wait For Line On Uart         Philosopher 5.*STARVING  treatAsRegex=true
208    Wait For Line On Uart         Philosopher 5.*HOLDING ONE FORK  treatAsRegex=true
209    Wait For Line On Uart         Philosopher 5.*EATING  treatAsRegex=true
210    Wait For Line On Uart         Philosopher 5.*THINKING  treatAsRegex=true
211
212Test Running the Zephyr Kernel FPU Sharing Generic Test
213    Create Machine
214    Execute Command               sysbus LoadELF ${ZEPHYR_FPU_SHARING_ELF}
215
216    Wait For Line On Uart         Booting Zephyr OS
217    Wait For Line On Uart         Running TESTSUITE fpu_sharing_generic
218
219    # The PASS line is currently printed after about 10.1 virtual seconds from the start.
220    Wait For Line On Uart         START - test_load_store
221    Wait For Line On Uart         PASS - test_load_store  timeout=12
222
223    # The test prints 5 "Pi calculation OK after X (high) + Y (low) tests" lines.
224    # Let's finish testing after the first one. It takes about 5 virtual seconds to
225    # reach it from the start and the whole test takes about 50 virtual seconds.
226    Wait For Line On Uart         START - test_pi
227    Wait For Line On Uart         Pi calculation OK
228
229Test Running the seL4 Adder Sample
230    Create Machine                gic_version=2
231    Execute Command               sysbus LoadELF ${SEL4_ADDER_ELF}
232    # seL4 expects to be at most in EL2
233    Execute Command               cpu SetAvailableExceptionLevels true false
234    # Initialize UART since we don't have a bootloader
235    Execute Command               ${UART} WriteDoubleWord 0x30 0x301
236    # Set 7-bit word length to hush the warning that 5-bit WLEN is unsupported.
237    Execute Command               ${UART} WriteDoubleWord 0x2c 0x40  #b10 << 5
238
239    Wait For Line On Uart         Booting all finished, dropped to user space
240    Wait For Line On Uart         client: what's the answer to 342 + 74 + 283 + 37 + 534 ?
241    Wait For Line On Uart         client: result was 1270
242