1*** Variables ***
2${UART}                                  sysbus.uart
3${COMMON_MEMORY}                         0x1400000
4${PER_CORE_MEMORY}                       0x3000000
5${CORE1_MEM_ALIAS}                       0x2010000
6${CORE2_MEM_ALIAS}                       0x2020000
7${UART_ADDR}                             0x50230000
8${UART_ADDR_MOVED}                       0x60230000
9${URI}                                   @https://dl.antmicro.com/projects/renode
10${TEST_ELF}                              ${URI}/multibus_test.elf-s_3718712-8ec6b7305242b1bfce702459d75ea02d04f00360
11
12${CPU1_OVERLAY_MEMORY}=     SEPARATOR=
13...  """                                                                             ${\n}
14...  cpu1_mem: Memory.ArrayMemory @ sysbus new Bus.BusPointRegistration {            ${\n}
15...  ${SPACE*4}address: 0x0;                                                         ${\n}
16...  ${SPACE*4}cpu: cpu1                                                             ${\n}
17...  }                                                                               ${\n}
18...  ${SPACE*4}size: 0x1000                                                          ${\n}
19...  """
20
21${CPU1_SHADOW_MEMORY}=     SEPARATOR=
22...  """                                                                             ${\n}
23...  cpu1_shadow_mem: Memory.ArrayMemory @ sysbus new Bus.BusPointRegistration {     ${\n}
24...  ${SPACE*4}address: 0xF00;                                                       ${\n}
25...  ${SPACE*4}cpu: cpu1                                                             ${\n}
26...  }                                                                               ${\n}
27...  ${SPACE*4}size: 0x1000                                                          ${\n}
28...  """
29
30
31*** Keywords ***
32Create Machine
33    [Arguments]  ${elf}
34
35    Execute Command                      mach create
36    Execute Command                      machine LoadPlatformDescription "${CURDIR}${/}per-core-registration.repl"
37
38    Execute Command                      macro reset "sysbus LoadELF ${elf}"
39    Execute Command                      runMacro $reset
40
41    Create Terminal Tester               ${UART}  timeout=1
42
43
44Create Machine With Hex File
45    [Arguments]  ${cpu}
46
47    Execute Command                      mach create
48    Execute Command                      machine LoadPlatformDescription "${CURDIR}${/}per-core-registration-hex.repl"
49
50    Execute Command                      sysbus LoadHEX @https://dl.antmicro.com/projects/renode/stm32f072b_disco--zephyr-hello_world.hex-s_34851-4e97c68491cf652d0becd549526cd3df56e8ae66 ${cpu}
51
52 Add Peripheral Move Hook
53    [Arguments]                          ${cpu}  ${hook_addr}  ${peripheral_addr}  ${new_address}
54    ${hook_script}=                      Catenate  SEPARATOR=\n
55                                         ...  from Antmicro.Renode.Peripherals.Bus import BusRangeRegistration
56                                         ...  uart_peripheral = machine.SystemBus.WhatIsAt(${peripheral_addr}, cpu).Peripheral
57                                         ...  new_registration = BusRangeRegistration(${new_address}, uart_peripheral.Size)
58                                         ...  machine.SystemBus.MoveRegistrationWithinContext(uart_peripheral, new_registration, cpu)
59    Execute Command                      ${cpu} AddHook ${hook_addr} """${hook_script}"""
60
61
62*** Test Cases ***
63Fail On Shadowing Other Registration
64           # Create machine with `ram` at 0x0 - 0x1FFFFFF.
65           Create Machine                ${TEST_ELF}
66
67           # Adding a CPU-specific peripheral over a global one is OK, accesses from that CPU will reach it instead.
68           Execute Command               machine LoadPlatformDescriptionFromString ${CPU1_OVERLAY_MEMORY}
69
70  # Adding another CPU-specific peripheral at address space already occupied for the given CPU should fail though.
71  ${out}=  Run Keyword And Expect Error  KeywordException:*
72           ...                           Execute Command
73           ...                           machine LoadPlatformDescriptionFromString ${CPU1_SHADOW_MEMORY}
74           Should Contain                ${out}     Error E39: Exception was thrown during registration
75           Should Contain                ${out}     conflicts with address
76
77  ${per}=  Execute Command               peripherals
78           Should Contain                ${per}     cpu1_mem
79           Should Not Contain            ${per}     cpu1_shadow_mem
80
81Get Same Read From Common Memory
82           Create Machine                ${TEST_ELF}
83
84           Execute Command               sysbus WriteDoubleWord ${COMMON_MEMORY} 0xDEADF00D
85           Start Emulation
86
87           Wait For Line On Uart         Core 0 read from ${COMMON_MEMORY} returned: 0xDEADF00D
88           Wait For Line On Uart         Core 1 read from ${COMMON_MEMORY} returned: 0xDEADF00D
89
90Values Written By One Core Should Not Be Visible By The Other One
91           Create Machine                ${TEST_ELF}
92
93           Start Emulation
94
95           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0x0
96           Wait For Line On Uart         Core 0 writing 0xB0B0B0B0 to per-core memory
97           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0xB0B0B0B0
98
99           Wait For Line On Uart         Core 1 read from ${PER_CORE_MEMORY} returned: 0x0
100           Wait For Line On Uart         Core 1 writing 0xBABABABA to per-core memory
101           Wait For Line On Uart         Core 1 read from ${PER_CORE_MEMORY} returned: 0xBABABABA
102
103           Provides                      Finished
104
105Write Values Using Sysbus
106           Create Machine                ${TEST_ELF}
107
108           Execute Command               sysbus.core1_mem WriteDoubleWord 0x0 0xFEEDFACE
109           Execute Command               sysbus.core2_mem WriteDoubleWord 0x0 0xFEE1DEAD
110           Start Emulation
111
112           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0xFEEDFACE
113           Wait For Line On Uart         Core 1 read from ${PER_CORE_MEMORY} returned: 0xFEE1DEAD
114
115Write Values Using Sysbus With Context
116           Create Machine                ${TEST_ELF}
117
118           Execute Command               sysbus WriteDoubleWord ${PER_CORE_MEMORY} 0xFEEDFACE sysbus.cpu1
119           Execute Command               sysbus WriteDoubleWord ${PER_CORE_MEMORY} 0xFEE1DEAD sysbus.cpu2
120           Start Emulation
121
122           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0xFEEDFACE
123           Wait For Line On Uart         Core 1 read from ${PER_CORE_MEMORY} returned: 0xFEE1DEAD
124
125Handle Being Simultaneously Registered On The Main Bus
126           Requires                      Finished
127
128  ${out}=  Execute Command               sysbus ReadDoubleWord ${CORE1_MEM_ALIAS}
129           Should Be Equal As Numbers    ${out}  0xB0B0B0B0
130  ${out}=  Execute Command               sysbus ReadDoubleWord ${CORE2_MEM_ALIAS}
131           Should Be Equal As Numbers    ${out}  0xBABABABA
132
133Read Values Using Sysbus Context
134           Requires                      Finished
135
136  ${out}=  Execute Command               sysbus ReadDoubleWord ${PER_CORE_MEMORY} sysbus.cpu1
137           Should Be Equal As Numbers    ${out}  0xB0B0B0B0
138  ${out}=  Execute Command               sysbus ReadDoubleWord ${PER_CORE_MEMORY} sysbus.cpu2
139           Should Be Equal As Numbers    ${out}  0xBABABABA
140
141Disassemble Code From Per Core Memory
142           Create Machine                ${TEST_ELF}
143
144           Execute Command               sysbus WriteDoubleWord ${PER_CORE_MEMORY} 0x1234 sysbus.cpu1
145           Execute Command               sysbus WriteDoubleWord ${PER_CORE_MEMORY} 0x5678 sysbus.cpu2
146
147  ${out}=  Execute Command               sysbus.cpu1 DisassembleBlock ${PER_CORE_MEMORY} 2
148           Should Contain                ${out}    addi
149
150  ${out}=  Execute Command               sysbus.cpu2 DisassembleBlock ${PER_CORE_MEMORY} 2
151           Should Contain                ${out}    lw
152Should Move Peripheral Registered Per Core
153           Create Machine                ${TEST_ELF}
154
155           # Verify expected UART registration
156  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR} sysbus.cpu1
157           Should Not Be Empty           ${out}
158  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR} sysbus.cpu2
159           Should Not Be Empty           ${out}
160  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR_MOVED} sysbus.cpu1
161           Should Be Empty               ${out}
162  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR_MOVED} sysbus.cpu2
163           Should Be Empty               ${out}
164
165           Add Peripheral Move Hook      sysbus.cpu2  `sysbus GetSymbolAddress "thread_entry"`  ${UART_ADDR}  ${UART_ADDR_MOVED}
166
167           Execute Command       showAnalyzer sysbus.uart
168           Execute Command               start
169
170           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0xB0B0B0B0
171
172           Run Keyword And Expect Error  InvalidOperationException: Terminal tester failed!*
173           ...                           Wait For Line On Uart
174           ...                           Core 1 read from ${PER_CORE_MEMORY} returned: 0xBABABABA
175
176           Execute Command               pause
177           Execute Command               sysbus.cpu2 RemoveHooksAt `sysbus GetSymbolAddress "thread_entry"`
178
179           Add Peripheral Move Hook      sysbus.cpu2  `sysbus GetSymbolAddress "thread_entry"`  ${UART_ADDR_MOVED}  ${UART_ADDR}
180
181           Clear Terminal Tester Report
182           Execute Command               runMacro $reset
183
184           # UART registration shouldn't reset
185  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR} sysbus.cpu1
186           Should Not Be Empty           ${out}
187  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR_MOVED} sysbus.cpu2
188           Should Not Be Empty           ${out}
189  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR_MOVED} sysbus.cpu1
190           Should Be Empty               ${out}
191  ${out}=  Execute Command               sysbus WhatIsAt ${UART_ADDR} sysbus.cpu2
192           Should Be Empty               ${out}
193
194           Execute Command               start
195
196           Wait For Line On Uart         Core 0 read from ${PER_CORE_MEMORY} returned: 0xB0B0B0B0
197           Wait For Line On Uart         Core 1 read from ${PER_CORE_MEMORY} returned: 0xBABABABA
198
199
200Should Not Load Hex To Invalid Core Specific Memory
201           Create Log Tester             0    # no need for additional timeout, we're only testing synchronous operations
202           Create Machine With Hex File  sysbus.cpu1
203           Wait For Log Entry            Tried to access bytes at non-existing peripheral
204
205
206Should Load Hex To Core Specific Memory
207           Create Log Tester             0    # no need for additional timeout, we're only testing synchronous operations
208           Create Machine With Hex File  sysbus.cpu2
209           Should Not Be In Log          Tried to access bytes at non-existing peripheral
210
211