*** Variables *** ${CPU_COUNT} 4 ${INIT_PERIPHBASE_ADDRESS} 0xAE000000 ${INIT_PERIPHBASE} 0x57000 ${NEW_PERIPHBASE_ADDRESS} 0x80000000 ${NEW_PERIPHBASE} 0x40000 ${REPL_PATH} platforms/cpus/cortex-r8_smp.repl ${SIGNALS_UNIT} signalsUnit ${GIC_MODEL} Antmicro.Renode.Peripherals.IRQControllers.ARM_GenericInterruptController ${PRIVATE_TIMER_MODEL} Antmicro.Renode.Peripherals.Timers.ARM_PrivateTimer ${SCU_MODEL} Antmicro.Renode.Peripherals.Miscellaneous.ArmSnoopControlUnit *** Keywords *** Create Cortex-R8 Machine [Arguments] ${scu_registration} Execute Command mach create Execute Command machine LoadPlatformDescriptionFromString "using \\"${REPL_PATH}\\"; scu: @ ${scu_registration}" Should Modify Peripheral Registration Verify Command Output As Integer 0x0 cpu0 GetSystemRegisterValue "CBAR" Execute Command emulation RunFor '0.0001' FOR ${i} IN RANGE ${CPU_COUNT} # SCU address is based on PERIPHBASE with zero offset. Verify Command Output As Integer ... ${INIT_PERIPHBASE_ADDRESS} cpu${i} GetSystemRegisterValue "CBAR" END Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PERIPHBASE" ${NEW_PERIPHBASE_ADDRESS} # Nothing changes before exiting from reset. Verify Peripherals Registered At ${INIT_PERIPHBASE_ADDRESS} Verify Command Output As Integer ... ${INIT_PERIPHBASE_ADDRESS} cpu1 GetSystemRegisterValue "CBAR" # Let's make sure the behavior is preserved across serialization. ${f}= Allocate Temporary File Execute Command Save @${f} Execute Command Clear Execute Command Load @${f} Execute Command mach set 0 FOR ${i} IN RANGE ${CPU_COUNT} Execute Command cpu${i} Reset END Execute Command emulation RunFor '0.0001' FOR ${i} IN RANGE ${CPU_COUNT} Verify Command Output As Integer ${NEW_PERIPHBASE_ADDRESS} cpu${i} GetSystemRegisterValue "CBAR" END Verify Peripherals Registered At ${NEW_PERIPHBASE_ADDRESS} Verify Command Output As Integer [Arguments] ${expected} ${command} ${output}= Execute Command ${command} Should Be Equal As Integers ${expected} ${output} base=16 Verify Command Output [Arguments] ${expected} ${command} ${output}= Execute Command ${command} Should Be Equal ${expected} ${output} strip_spaces=True Verify PERIPHBASE Init Value Verify Command Output As Integer ${INIT_PERIPHBASE_ADDRESS} ${SIGNALS_UNIT} GetAddress "PERIPHBASE" Verify Peripherals Registered At [Arguments] ${address} FOR ${i} IN RANGE ${CPU_COUNT} Verify Command Output ... ${SCU_MODEL} sysbus WhatPeripheralIsAt ${address} cpu${i} Verify Command Output ... ${GIC_MODEL} sysbus WhatPeripheralIsAt ${${address} + 0x100} cpu${i} # CPU interface Verify Command Output ... ${GIC_MODEL} sysbus WhatPeripheralIsAt ${${address} + 0x1000} cpu${i} # distributor Verify Command Output ... ${PRIVATE_TIMER_MODEL} sysbus WhatPeripheralIsAt ${${address} + 0x600} cpu${i} END Verify PCs [Arguments] ${cpu0_pc_expected} ${cpu1_pc_expected} Verify Command Output As Integer ${cpu0_pc_expected} cpu0 PC Verify Command Output As Integer ${cpu1_pc_expected} cpu1 PC *** Test Cases *** Create Machine With SCU Registered Create Cortex-R8 Machine scu_registration=sysbus ${INIT_PERIPHBASE_ADDRESS} Provides created-cr8-machine Should Gracefully Handle Invalid Signal Requires created-cr8-machine # All available signals should be printed with both names when the given signal can't be found. # Let's just check if two example signals are included: INITRAM and PERIPHBASE. Run Keyword And Expect Error *No such signal: ''\nAvailable signals are:*INITRAM (InitializeInstructionTCM)* ... Execute Command ${SIGNALS_UNIT} GetSignal "" Run Keyword And Expect Error *No such signal: 'INVALID'\nAvailable signals are:*PERIPHBASE (PeripheralsBase)* ... Execute Command ${SIGNALS_UNIT} GetSignal "INVALID" Should Handle Addresses Requires created-cr8-machine Verify PERIPHBASE Init Value Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PERIPHBASE" ${NEW_PERIPHBASE_ADDRESS} Verify Command Output As Integer ${NEW_PERIPHBASE_ADDRESS} ${SIGNALS_UNIT} GetAddress "PERIPHBASE" # When set from address, the signal is set to a value based on address' top bits. Verify Command Output As Integer ${NEW_PERIPHBASE} ${SIGNALS_UNIT} GetSignal "PERIPHBASE" Create Log Tester 0 # DBGROMADDR is a 20-bit signal, let's first set it to a non-zero value. ${exp_value}= Set Variable 0x12345 ${address}= Set Variable ${exp_value}000 ${signal}= Set Variable DebugROMAddress Execute Command ${SIGNALS_UNIT} SetSignalFromAddress ${signal} ${address} # Setting signals from addresses with bits over 32 set is invalid for Cortex-R8 even though only top 20 bits are set. ${address_64b}= Set Variable 0xFEDCB00000000000 Run Keyword And Expect Error *${SIGNALS_UNIT}: ${signal}: 20-bit signal in a 32-bit unit shouldn't be set from ${address_64b} address* ... Execute Command ${SIGNALS_UNIT} SetSignalFromAddress ${signal} ${address_64b} # Valid address/value should be preserved. Verify Command Output As Integer ${address} ${SIGNALS_UNIT} GetAddress ${signal} Verify Command Output As Integer ${exp_value} ${SIGNALS_UNIT} GetSignal ${signal} # PFILTERSTART is a 12-bit signal so setting it from an address with any of bits 0-19 set should fail. ${address}= Set Variable 0x12340000 ${signal}= Set Variable PeripheralFilterStart Run Keyword And Expect Error *${SIGNALS_UNIT}: ${signal}: 12-bit signal in a 32-bit unit shouldn't be set from ${address} address* ... Execute Command ${SIGNALS_UNIT} SetSignalFromAddress ${signal} ${address} # Make sure it stayed zero. Verify Command Output As Integer 0x0 ${SIGNALS_UNIT} GetAddress ${signal} Verify Command Output As Integer 0x0 ${SIGNALS_UNIT} GetSignal ${signal} Should Modify Peripheral Registration With SCU Registered Requires created-cr8-machine Verify Command Output As Integer ${INIT_PERIPHBASE} ${SIGNALS_UNIT} GetSignal "PERIPHBASE" Verify Peripherals Registered At ${INIT_PERIPHBASE_ADDRESS} Should Modify Peripheral Registration Should Modify Peripheral Registration With SCU Unregistered Create Cortex-R8 Machine scu_registration=sysbus # SCU initially unregistered, PERIPHBASE not automatically set as when SCU registered at a specific address. Verify Command Output As Integer 0x0 ${SIGNALS_UNIT} GetSignal "PERIPHBASE" # There should be no peripheral at INIT_PERIPHBASE where SCU is registered by default. ${peripherals}= Execute Command peripherals Should Not Contain ${peripherals} ${INIT_PERIPHBASE_ADDRESS} # Now let's set PERIPHBASE which will register SCU there on CPU out of reset and test modifying registrations. Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PERIPHBASE" ${INIT_PERIPHBASE_ADDRESS} Should Modify Peripheral Registration ${peripherals}= Execute Command peripherals Should Set PC For Cores With INITRAM And VINITHI High Requires created-cr8-machine Execute Command cpu0 ExecutionMode SingleStep Execute Command cpu1 ExecutionMode SingleStep # Both signals will be high only for cpu0. Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "INITRAM" true cpu0 Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "INITRAM" true cpu1 Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "VINITHI" true cpu0 Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "VINITHI" false cpu1 Verify PCs 0x0 0x0 Start Emulation Verify PCs 0xFFFF0000 0x0 Execute Command cpu0 PC 0x12345678 Execute Command cpu1 PC 0x90ABCDE0 # PCs are set immediately because machine is started right after Reset if it was started before. Execute Command machine Reset Verify PCs 0xFFFF0000 0x0 # Now both signals will be high only for cpu1. # Setting signals shouldn't influence PCs before starting-after-reset. Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "VINITHI" false cpu0 Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "VINITHI" true cpu1 Verify PCs 0xFFFF0000 0x0 Execute Command cpu0 Reset Execute Command cpu1 Reset Verify PCs 0x0 0x0 Execute Command cpu0 Start Execute Command cpu1 Start Verify PCs 0x0 0xFFFF0000 Verify PERIPHBASE Init Value With CPU-specific SCU Registrations Execute Command mach create ${PLATFORM}= Catenate SEPARATOR=\n ... signalsUnit: Miscellaneous.CortexR8SignalsUnit @ sysbus ... ${SPACE*4}snoopControlUnit: scu ... ... cpu0: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r8" ... ${SPACE*4}cpuId: 0 ... ${SPACE*4}signalsUnit: signalsUnit ... ... cpu1: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r8" ... ${SPACE*4}cpuId: 1 ... ${SPACE*4}signalsUnit: signalsUnit ... ... scu: Miscellaneous.ArmSnoopControlUnit @ { ... ${SPACE*4}sysbus new Bus.BusPointRegistration { address: 0xae000000; cpu: cpu0 }; ... ${SPACE*4}sysbus new Bus.BusPointRegistration { address: 0xae000000; cpu: cpu1 } ... } Execute Command machine LoadPlatformDescriptionFromString """${PLATFORM}""" Verify PERIPHBASE Init Value Registration Of Unsupported CPU Should Not Be Allowed From The Monitor Requires created-cr8-machine ${CR5_CPU}= Catenate SEPARATOR=\n ... cr5: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r5" ... ${SPACE*4}cpuId: 5 Execute Command machine LoadPlatformDescriptionFromString """${CR5_CPU}""" ${MESSAGE}= Catenate SEPARATOR=${SPACE} ... *Tried to register unsupported CPU model to CortexR8SignalsUnit: cortex-r5; ... supported CPUs are: cortex-r8* Run Keyword And Expect Error ${MESSAGE} ... Execute Command ${SIGNALS_UNIT} RegisterCPU cr5 Registration Of Unsupported CPU Should Not Be Allowed From Platform Description Execute Command mach create ${CR8_CPU}= Catenate SEPARATOR=\n ... ${SIGNALS_UNIT}: Miscellaneous.CortexR5SignalsUnit @ sysbus ... ... cpu: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r8" ... ${SPACE*4}signalsUnit: ${SIGNALS_UNIT} ${MESSAGE}= Catenate SEPARATOR=${SPACE} ... *Tried to register unsupported CPU model to CortexR5SignalsUnit: cortex-r8; ... supported CPUs are: cortex-r5, cortex-r5f* Run Keyword And Expect Error ${MESSAGE} ... Execute Command machine LoadPlatformDescriptionFromString """${CR8_CPU}""" Create Machine With Cortex-R5 And Cortex-R5F Execute Command mach create ${PLATFORM}= Catenate SEPARATOR=\n ... ${SIGNALS_UNIT}: Miscellaneous.CortexR5SignalsUnit @ sysbus ... ... cpu0: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r5f" ... ${SPACE*4}cpuId: 0 ... ${SPACE*4}signalsUnit: ${SIGNALS_UNIT} ... ... cpu1: CPU.ARMv7R @ sysbus ... ${SPACE*4}cpuType: "cortex-r5" ... ${SPACE*4}cpuId: 1 ... ${SPACE*4}signalsUnit: ${SIGNALS_UNIT} Execute Command machine LoadPlatformDescriptionFromString """${PLATFORM}""" Provides created-cr5-machine Set Cortex-R5 Peripheral Interface Region Registers With Signals Requires created-cr5-machine # So that there's no CPU abort after starting emulation which is also why SingleStep is used. Execute Command machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x0 { size: 0x10000 }" # Base can be up to 20 bits. Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PPHBASE" 0x12345000 Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PPXBASE" 0x60007000 Execute Command ${SIGNALS_UNIT} SetSignalFromAddress "PPVBASE" 0x00089000 # Size can be up to 5 bits. Execute Command ${SIGNALS_UNIT} SetSignal "PPHSIZE" 0x1F Execute Command ${SIGNALS_UNIT} SetSignal "PPXSIZE" 0x10 Execute Command ${SIGNALS_UNIT} SetSignal "PPVSIZE" 0x0F FOR ${i} IN RANGE 2 # Init is a per-cpu signal, there's no init signal for Virtual AXI Interface Region Register (PPVR). Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "INITPPH" false cpu${i} Execute Command ${SIGNALS_UNIT} SetSignalStateForCPU "INITPPX" true cpu${i} # Configuration signals take effect on CPU out of reset. Verify Command Output As Integer 0x0 cpu${i} GetSystemRegisterValue "PPHR" Verify Command Output As Integer 0x0 cpu${i} GetSystemRegisterValue "PPXR" Verify Command Output As Integer 0x0 cpu${i} GetSystemRegisterValue "PPVR" # Continuous code execution would quickly reach 0x10000 and cause CPU abort. Execute Command cpu${i} ExecutionMode SingleStep END Start Emulation FOR ${i} IN RANGE 2 Verify Command Output As Integer ${{ hex(0x12345000 | (0x1F << 2) | 0) }} cpu${i} GetSystemRegisterValue "PPHR" Verify Command Output As Integer ${{ hex(0x60007000 | (0x10 << 2) | 1) }} cpu${i} GetSystemRegisterValue "PPXR" Verify Command Output As Integer ${{ hex(0x00089000 | (0x0F << 2) | 0) }} cpu${i} GetSystemRegisterValue "PPVR" END