288 lines
14 KiB
Plaintext
288 lines
14 KiB
Plaintext
*** Variables ***
|
|
${UART} sysbus.mmuart1
|
|
${URI} @https://dl.antmicro.com/projects/renode
|
|
${PLATFORM} @platforms/cpus/polarfire-soc.repl
|
|
${SHARED_VARIABLE_ADDRESS} 0x81000000
|
|
${VARIABLE_ADDRESS_CPU1} 0x81000000
|
|
${VARIABLE_ADDRESS_CPU2} 0x81000100
|
|
${LOOP_ITERATIONS} 100
|
|
${CORE_1_PC} 0x80000000
|
|
${CORE_2_PC} 0x80000100
|
|
${VARIABLE_VALUE} 0x5
|
|
${NEW_VARIABLE_VALUE} 0xbeeeeeef
|
|
|
|
# Registers used
|
|
${x0} 0
|
|
${a0} 10
|
|
${a1} 11
|
|
${a2} 12
|
|
${a3} 13
|
|
${a4} 14
|
|
|
|
# Repeatedly increments the value in (a0) until enough loop iterations have run.
|
|
${ASSEMBLY_LRSC_LOOP} SEPARATOR=
|
|
... repeat: lr.d a4, (a0);
|
|
... add a4, a4, a2;
|
|
... sc.d a4, a4, (a0);
|
|
... bnez a4, repeat;
|
|
... addi a1, a1, -1;
|
|
... bnez a1, repeat;
|
|
... j 0;
|
|
|
|
*** Keywords ***
|
|
Create Machine
|
|
Execute Command mach create
|
|
Execute Command machine LoadPlatformDescription ${PLATFORM}
|
|
Execute Command sysbus.u54_1 ExecutionMode SingleStep
|
|
Execute Command sysbus.u54_2 ExecutionMode SingleStep
|
|
Execute Command sysbus.u54_1 PC ${CORE_1_PC}
|
|
Execute Command sysbus.u54_2 PC ${CORE_2_PC}
|
|
|
|
Execute Command sysbus.u54_3 IsHalted true
|
|
Execute Command sysbus.u54_4 IsHalted true
|
|
Execute Command sysbus.e51 IsHalted true
|
|
|
|
|
|
Assemble Instruction
|
|
[Arguments] ${cpu} ${mnemonic} ${operands}= ${address}=0
|
|
${len}= Execute Command sysbus.${cpu} AssembleBlock ${address} "${mnemonic} ${operands}"
|
|
|
|
Create Reservations
|
|
# Just write 5 to memory, we'll use this to check for successful and failed writes
|
|
Execute Command sysbus WriteDoubleWord ${VARIABLE_ADDRESS_CPU1} ${VARIABLE_VALUE}
|
|
Execute Command sysbus WriteDoubleWord ${VARIABLE_ADDRESS_CPU2} ${VARIABLE_VALUE}
|
|
|
|
# Make a0 hold the memory address
|
|
|
|
# li a0, ${VARIABLE_ADDRESS_CPU1} (two instructions)
|
|
Assemble Instruction u54_1 li a0, ${VARIABLE_ADDRESS_CPU1} 0x80000000
|
|
Execute Command sysbus.u54_1 Step 2
|
|
Register Should Be Equal ${a0} ${VARIABLE_ADDRESS_CPU1} cpuName=u54_1
|
|
|
|
# li a0, ${VARIABLE_ADDRESS_CPU2} (three instructions)
|
|
Assemble Instruction u54_2 li a0, ${VARIABLE_ADDRESS_CPU2} 0x80000100
|
|
Execute Command sysbus.u54_2 Step 3
|
|
Register Should Be Equal ${a0} ${VARIABLE_ADDRESS_CPU2} cpuName=u54_2
|
|
|
|
# Create reservation on first core
|
|
Assemble Instruction u54_1 lr.d a1, (a0) 0x80000006
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a1} ${VARIABLE_VALUE} cpuName=u54_1
|
|
|
|
# Create reservation on second core
|
|
Assemble Instruction u54_2 lr.d a1, (a0) 0x8000010A
|
|
Execute Command sysbus.u54_2 Step
|
|
Register Should Be Equal ${a1} ${VARIABLE_VALUE} cpuName=u54_2
|
|
|
|
Contended Memory Value Should Increment To Correct Sum
|
|
[Arguments]
|
|
... ${assembly_loop_core_1}
|
|
... ${assembly_loop_core_2}
|
|
Create Machine
|
|
|
|
Execute Command sysbus.u54_1 ExecutionMode Continuous
|
|
Execute Command sysbus.u54_2 ExecutionMode Continuous
|
|
|
|
Execute Command logLevel 0
|
|
|
|
# Repeatedly increment a memory location from two cores
|
|
|
|
${shared_memory_counter}= Set Variable 0x80000600
|
|
${counter_start_value}= Set Variable 0
|
|
${increments_per_core}= Set Variable 10000000
|
|
${increment_step_size}= Set Variable 1
|
|
|
|
# Initialize shared memory counter.
|
|
Execute Command sysbus WriteQuadWord ${shared_memory_counter} ${counter_start_value}
|
|
|
|
# Set up registers for first core.
|
|
Execute Command u54_1 SetRegister ${a0} ${shared_memory_counter}
|
|
Execute Command u54_1 SetRegister ${a1} ${increments_per_core}
|
|
Execute Command u54_1 SetRegister ${a2} ${increment_step_size}
|
|
Execute Command u54_1 SetRegister ${a3} 0x1234
|
|
|
|
# Set up registers for second core.
|
|
Execute Command u54_2 SetRegister ${a0} ${shared_memory_counter}
|
|
Execute Command u54_2 SetRegister ${a1} ${increments_per_core}
|
|
Execute Command u54_2 SetRegister ${a2} ${increment_step_size}
|
|
Execute Command u54_2 SetRegister ${a3} 0x1234
|
|
|
|
# Place machine code at PC for both cores.
|
|
${assembly_size_1}= Execute Command u54_1 AssembleBlock ${CORE_1_PC} "${assembly_loop_core_1}"
|
|
${assembly_size_2}= Execute Command u54_2 AssembleBlock ${CORE_2_PC} "${assembly_loop_core_2}"
|
|
|
|
# Calculate end addresses.
|
|
# The -2 is for the 'j 0' and needs to be put at the start due to weird robot/python string conversion
|
|
${core_1_end_pc}= Evaluate -2 + ${CORE_1_PC} + ${assembly_size_1}
|
|
${core_2_end_pc}= Evaluate -2 + ${CORE_2_PC} + ${assembly_size_2}
|
|
|
|
# For detecting when loops are finished.
|
|
Create Log Tester 0
|
|
|
|
# Print when exiting loop.
|
|
Execute Command u54_1 AddHook ${core_1_end_pc} "self.InfoLog('u54_1 finished'); self.IsHalted = True"
|
|
Execute Command u54_2 AddHook ${core_2_end_pc} "self.InfoLog('u54_2 finished'); self.IsHalted = True"
|
|
|
|
# Wait for the loops to finish...
|
|
Wait For Log Entry u54_1 finished timeout=10 keep=true
|
|
Wait For Log Entry u54_2 finished timeout=10 keep=true
|
|
|
|
# In the end, the shared memory counter should've been incremented 2*increments_per_core times.
|
|
${counter_final_value}= Execute Command sysbus ReadQuadWord ${shared_memory_counter}
|
|
Should Be Equal As Integers ${counter_final_value} ${2 * ${increments_per_core}} "Counter should now have been incremented to ${2 * ${increments_per_core}} but it contains ${counter_final_value}"
|
|
|
|
*** Test Cases ***
|
|
Should Handle Multiple Writes To Same Reservation
|
|
Create Machine
|
|
Create Reservations
|
|
|
|
# Try to update memory address with number 6
|
|
# This will check if simple LR/SC behaves correctly
|
|
|
|
Assemble Instruction u54_1 li a2, 0x6 0x8000000A
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a2} 0x6 cpuName=u54_1
|
|
|
|
# Check for successful SC
|
|
Assemble Instruction u54_1 sc.d a3, a2, (a0) 0x8000000C
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a3} 0x0 cpuName=u54_1
|
|
|
|
${res}= Execute Command sysbus ReadDoubleWord ${VARIABLE_ADDRESS_CPU1}
|
|
Should Be Equal As Integers ${res} 6
|
|
|
|
# Try to SC on something that isn't reserved - this should fail (returns 1)
|
|
|
|
Assemble Instruction u54_1 sc.d a3, zero, (a0) 0x80000010
|
|
Execute Command sysbus.u54_1 Step
|
|
|
|
# Check if SC failed (correct behavior)
|
|
Register Should Be Equal ${a3} 0x1 cpuName=u54_1
|
|
|
|
${res}= Execute Command sysbus ReadDoubleWord ${VARIABLE_ADDRESS_CPU1}
|
|
Should Be Equal As Integers ${res} 0x00000006
|
|
|
|
Should Work On Multiple Cores
|
|
Create Machine
|
|
Create Reservations
|
|
|
|
# Having reservations on two cores, we try to store on both of them
|
|
|
|
Assemble Instruction u54_1 li a2, 0x6 0x8000000A
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a2} 0x6 cpuName=u54_1
|
|
|
|
Assemble Instruction u54_2 li a2, 0x7 0x8000010E
|
|
Execute Command sysbus.u54_2 Step
|
|
Register Should Be Equal ${a2} 0x7 cpuName=u54_2
|
|
|
|
# Check for successful store on second core
|
|
Assemble Instruction u54_2 sc.d a3, a2, (a0) 0x80000110
|
|
Execute Command sysbus.u54_2 Step
|
|
Register Should Be Equal ${a3} 0x0 cpuName=u54_2
|
|
|
|
# Check for successful store on first core
|
|
Assemble Instruction u54_1 sc.d a3, a2, (a0) 0x8000000C
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a3} 0x0 cpuName=u54_1
|
|
|
|
Should Drop Other Core Reservation On SC
|
|
Create Machine
|
|
Create Reservations
|
|
|
|
# Check if SC on other core's LR will drop the reservation
|
|
|
|
Assemble Instruction u54_1 li a2, 0x6 0x8000000A
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a2} 0x6 cpuName=u54_1
|
|
|
|
# Get the address of second core's reservation to first core's a0
|
|
Assemble Instruction u54_1 li a0, ${VARIABLE_ADDRESS_CPU2} 0x8000000C
|
|
Execute Command sysbus.u54_1 Step 3
|
|
Register Should Be Equal ${a0} ${VARIABLE_ADDRESS_CPU2} cpuName=u54_1
|
|
|
|
# Try to store on second core's reservation
|
|
Assemble Instruction u54_1 sc.d a3, a2, (a0) 0x80000016
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a3} 0x1 cpuName=u54_1
|
|
|
|
# Try to store on second core's reservation by second core
|
|
Assemble Instruction u54_2 sc.d a3, a2, (a0) 0x80000110
|
|
Execute Command sysbus.u54_2 Step
|
|
Register Should Be Equal ${a3} 0x0 cpuName=u54_2
|
|
|
|
Should Handle Looping LR/SC Pairs To Same Reservation
|
|
Create Machine
|
|
|
|
${start_value}= Set Variable 0
|
|
|
|
Execute Command sysbus WriteDoubleWord ${VARIABLE_ADDRESS_CPU1} ${start_value}
|
|
|
|
# Repeatedly increment a memory location on one core
|
|
|
|
# The assembly instructions to execute in this test.
|
|
# It repeatedly increments the value in (a0) until enough loop iterations have run.
|
|
${ASSEMBLY_LRSC_LOOP}= catenate SEPARATOR=
|
|
... repeat: lr.w a4, (a0);
|
|
... addi a4, a4, 1;
|
|
... sc.w a4, a4, (a0);
|
|
... bnez a4, repeat;
|
|
... addi a1, a1, -1;
|
|
... bnez a1, repeat;
|
|
... j 0;
|
|
|
|
# Set up registers
|
|
Execute Command u54_1 SetRegister ${a0} ${VARIABLE_ADDRESS_CPU1}
|
|
Execute Command u54_1 SetRegister ${a1} ${LOOP_ITERATIONS}
|
|
|
|
# Place machine code at PC.
|
|
Execute Command sysbus.u54_1 AssembleBlock 0x80000000 "${ASSEMBLY_LRSC_LOOP}"
|
|
|
|
FOR ${i} IN RANGE ${start_value} ${LOOP_ITERATIONS}
|
|
${next_i}= Set Variable ${${i} + 1}
|
|
|
|
# Execute lr.w, which should give the memory counter value
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a4} ${i} cpuName=u54_1
|
|
|
|
# Execute addi, which should increment the counter value
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a4} ${next_i} cpuName=u54_1
|
|
|
|
# Execute sc.w, which should succeed in storing the incremented value to memory
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a4} 0 cpuName=u54_1
|
|
${res}= Execute Command sysbus ReadDoubleWord ${VARIABLE_ADDRESS_CPU1}
|
|
Should Be Equal As Integers ${res} ${next_i} "Memory location should now contain ${next_i} but it contains ${res}"
|
|
|
|
# bnez shouldn't need to jump to repeat, just step over it.
|
|
Execute Command sysbus.u54_1 Step
|
|
|
|
# Check for successful decrement of loop counter
|
|
Execute Command sysbus.u54_1 Step
|
|
Register Should Be Equal ${a1} ${${LOOP_ITERATIONS} - ${next_i}} cpuName=u54_1
|
|
|
|
# jump back to start of next loop (if not at final iteration)
|
|
Execute Command sysbus.u54_1 Step
|
|
END
|
|
|
|
# In the end, it should've been incremented LOOP_ITERATIONS times.
|
|
Register Should Be Equal ${a1} 0 cpuName=u54_1
|
|
${res}= Execute Command sysbus ReadDoubleWord ${VARIABLE_ADDRESS_CPU1}
|
|
Should Be Equal As Integers ${res} ${LOOP_ITERATIONS} "Memory location should now have been incremented to ${LOOP_ITERATIONS} but it contains ${res}"
|
|
|
|
Two LR/SC Loops Should Increment To Correct Sum
|
|
Contended Memory Value Should Increment To Correct Sum
|
|
... assembly_loop_core_1=${ASSEMBLY_LRSC_LOOP}
|
|
... assembly_loop_core_2=${ASSEMBLY_LRSC_LOOP}
|
|
|
|
LR/SC And Amoadd Loops Should Increment To Correct Sum
|
|
${ASSEMBLY_AMOADD_LOOP}= catenate SEPARATOR=
|
|
... repeat: amoadd.d x0, a2, (a0);
|
|
... addi a1, a1, -1;
|
|
... bnez a1, repeat;
|
|
... j 0;
|
|
Contended Memory Value Should Increment To Correct Sum
|
|
... assembly_loop_core_1=${ASSEMBLY_AMOADD_LOOP}
|
|
... assembly_loop_core_2=${ASSEMBLY_LRSC_LOOP}
|