blob: 4d2f093cca927526cfc1ceda6d3ed498ddc86a80 [file] [log] [blame]
*** Variables ***
# RISC-V registers
${a1} 0xb
${starting_pc} 0x2000
${next_instruction} 0x2004
${mtvec} 0x1010
${illegal_instruction} 0x2
${load_misaligned} 0x4
${store_misaligned} 0x6
${register_0} 0x0
${illegal_opcode} 0x00008000
${illegal_csr} 0xf120d073
${nonexisting_csr} 0xfff0d073
*** Keywords ***
Create Machine
[Arguments] ${bitness} ${init_pc}
Execute Command using sysbus
Execute Command mach create "risc-v"
Execute Command machine LoadPlatformDescriptionFromString "clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x44000000 { frequency: 66000000 }"
Execute Command machine LoadPlatformDescriptionFromString "cpu: CPU.RiscV${bitness} @ sysbus { timeProvider: clint; cpuType: \\"rv${bitness}gc\\" }"
Execute Command machine LoadPlatformDescriptionFromString "mem: Memory.MappedMemory @ sysbus 0x1000 { size: 0x40000 }"
IF ${init_pc}
Execute Command cpu PC ${starting_pc}
END
Create Machine 32
Create Machine bitness=32 init_pc=True
Create Machine 64
Create Machine bitness=64 init_pc=True
Write Opcode To
[Arguments] ${adress} ${opcode}
Execute Command sysbus WriteDoubleWord ${adress} ${opcode}
Load Program With Invalid Instruction
[Arguments] ${address}
${addi_opcode} Set Variable 0x00050593 #addi x11 x10 0
${vector_opcode} Set Variable 0x00000057 #vadd.vv v0, v0, v0, v0.t
${fvf_vector_opcode} Set Variable 0x00005057 #vfadd.vf v0, v0, ft0, v0.t
${start_pc}= Convert To Integer ${address}
# Depending on the fact if vector extension is enabled or not, the program will cause
# invalid instruction exception at ${vector_opcode} or ${fvf_vector_opcode}.
Write Opcode To ${start_pc} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+4} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+8} ${vector_opcode} #vadd.vv v0, v0, v0, v0.t
Write Opcode To ${start_pc+12} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+16} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+20} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+24} ${fvf_vector_opcode} #vfadd.vf v0, v0, ft0, v0.t
Write Opcode To ${start_pc+28} ${addi_opcode} #addi x11 x10 0
Write Opcode To ${start_pc+32} ${vector_opcode} #vadd.vv v0, v0, v0, v0.t
Write Opcode To ${start_pc+36} ${addi_opcode} #addi x11 x10 0
Set ResetVector And Verify PC
[Arguments] ${reset_vector} ${should_set_pc}
IF ${should_set_pc}
${expected_pc}= Set Variable ${reset_vector}
ELSE
${expected_pc}= Execute Command cpu PC
END
Execute Command cpu ResetVector ${reset_vector}
Verify PC ${expected_pc}
Should Properly Handle ResetVector
# Setting ResetVector before setting PC directly, with LoadELF etc. should propagate to PC.
Set ResetVector And Verify PC 0x1234 should_set_pc=True
Set ResetVector And Verify PC 0x1238 should_set_pc=True
# Setting PC other than as an effect of ResetVector should stop the propagation.
${new_reset_vector_value}= Set Variable 0x123C
Execute Command cpu PC 0x5678
Set ResetVector And Verify PC ${new_reset_vector_value} should_set_pc=False
# Reset should set PC to ResetVector and restore PC propagation on ResetVector.
Execute Command cpu Reset
Verify PC ${new_reset_vector_value}
Set ResetVector And Verify PC 0x1240 should_set_pc=True
Should Properly Handle ResetVector At Init And After Reset
Verify PC 0x1000 # Default ResetVector
Should Properly Handle ResetVector
${new_reset_vector_value}= Set Variable 0x2468
Execute Command cpu ResetVector ${new_reset_vector_value}
Execute Command cpu Reset
Verify PC ${new_reset_vector_value}
Should Properly Handle ResetVector
Verify PC
[Arguments] ${expected_pc}
${pc}= Execute Command cpu PC
Should Be Equal As Integers ${pc} ${expected_pc}
*** Test Cases ***
Should Handle LB
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# lb a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00558503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Handle LH
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000001
# lh a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00559503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail LH
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# lh a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00559503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${load_misaligned}
Should Handle LW
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000003
# lw a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0055a503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail LW
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# lw a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0055a503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${load_misaligned}
Should Handle LD
Create Machine 64
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000003
# ld a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0055b503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail LD
Create Machine 64
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# ld a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0055b503
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${load_misaligned}
Should Handle SB
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# sb a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a582a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Handle SH
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000001
# sh a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a592a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail SH
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# sh a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a592a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${store_misaligned}
Should Handle SW
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000003
# sw a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a5a2a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail SW
Create Machine 32
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000000
# sw a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a5a2a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${store_misaligned}
Should Handle SD
Create Machine 64
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000003
# sd a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a5b2a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${next_instruction}
Should Fail SD
Create Machine 64
Execute Command cpu SetRegisterUnsafe ${a1} 0x00000001
# sd a0, 0x00000005(a1)
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x00a5b2a3
Execute Command cpu Step
${pc}= Execute Command cpu PC
Should Be Equal As Numbers ${pc} ${mtvec}
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${store_misaligned}
Should Fail On Setting X0 register
Create Machine 32
${msg}= Run Keyword And Expect Error * Execute Command cpu SetRegisterUnsafe ${register_0} 0x00000001
Should Contain ${msg} register is read-only
Register Should Be Equal 0 0x0
Should Set MEPC on Illegal Instruction
Create Machine 32
# j .
Execute Command sysbus WriteDoubleWord 0x1010 0x0000006f
# j 0x4000
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0000206f
# nop
Execute Command sysbus WriteDoubleWord 0x4000 0x00000013
# ILLEGAL INSTRUCTION
Execute Command sysbus WriteDoubleWord 0x4004 ${illegal_opcode}
Execute Command cpu Step 3
PC Should Be Equal 0x1010
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${illegal_instruction}
${mtval}= Execute Command cpu MTVAL
Should Be Equal As Numbers ${mtval} ${illegal_opcode}
${mepc}= Execute Command cpu MEPC
Should Be Equal As Numbers ${mepc} 0x4004
Should Set MEPC on Illegal CSR access
Create Machine 32
Execute Command cpu CSRValidation Full
# j .
Execute Command sysbus WriteDoubleWord 0x1010 0x0000006f
# j 0x4000
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0000206f
# nop
Execute Command sysbus WriteDoubleWord 0x4000 0x00000013
# csrwi marchid, 1 - this is an illegal CSR operation as `marchid` is read-only
Execute Command sysbus WriteDoubleWord 0x4004 ${illegal_csr}
Execute Command cpu Step 3
PC Should Be Equal 0x1010
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${illegal_instruction}
${mtval}= Execute Command cpu MTVAL
Should Be Equal As Numbers ${mtval} ${illegal_csr}
${mepc}= Execute Command cpu MEPC
Should Be Equal As Numbers ${mepc} 0x4004
Should Set MEPC on Non-Existing CSR access
Create Machine 32
# j .
Execute Command sysbus WriteDoubleWord 0x1010 0x0000006f
# j 0x4000
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0000206f
# nop
Execute Command sysbus WriteDoubleWord 0x4000 0x00000013
# csrwi marchid, 1 - this is an illegal CSR operation as `marchid` is read-only
Execute Command sysbus WriteDoubleWord 0x4004 ${nonexisting_csr}
Execute Command cpu Step 3
PC Should Be Equal 0x1010
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${illegal_instruction}
${mtval}= Execute Command cpu MTVAL
Should Be Equal As Numbers ${mtval} ${nonexisting_csr}
${mepc}= Execute Command cpu MEPC
Should Be Equal As Numbers ${mepc} 0x4004
Should Set MEPC on Wrong SRET
Create Machine 32
# j .
Execute Command sysbus WriteDoubleWord 0x1010 0x0000006f
# j 0x4000
Execute Command sysbus WriteDoubleWord ${starting_pc} 0x0000206f
# nop
Execute Command sysbus WriteDoubleWord 0x4000 0x00000013
# csrwi marchid, 1 - this is an illegal CSR operation as `marchid` is read-only
Execute Command sysbus WriteDoubleWord 0x4004 0x10200073
Execute Command cpu Step 3
PC Should Be Equal 0x1010
${mcause}= Execute Command cpu MCAUSE
Should Be Equal As Numbers ${mcause} ${illegal_instruction}
${mtval}= Execute Command cpu MTVAL
Should Be Equal As Numbers ${mtval} 0x10200073
${mepc}= Execute Command cpu MEPC
Should Be Equal As Numbers ${mepc} 0x4004
Should Exit Translation Block After Invalid Instruction And Report Single Error
Create Machine 32
Load Program With Invalid Instruction ${starting_pc}
Create Log Tester 3
${start_pc}= Convert To Integer ${starting_pc}
${illegal_opcode_1_pc} Set Variable ${start_pc+8}
${illegal_opcode_1_pc_hex}= Convert To Hex ${illegal_opcode_1_pc}
${illegal_opcode_2_pc} Set Variable ${start_pc+24}
${illegal_opcode_2_pc_hex}= Convert To Hex ${illegal_opcode_2_pc}
${illegal_opcode_3_pc} Set Variable ${start_pc+32}
${illegal_opcode_3_pc_hex}= Convert To Hex ${illegal_opcode_3_pc}
# It doesn't use single stepping on purpose, as it would cause translation blocks of size 1.
Execute Command cpu PerformanceInMips 1
Execute Command emulation SetGlobalQuantum "0.000020"
Execute Command emulation RunFor "0.000010"
Wait For Log Entry instruction set is not enabled for this CPU! PC: 0x${illegal_opcode_1_pc_hex}
Should Not Be In Log instruction set is not enabled for this CPU! PC: 0x${illegal_opcode_2_pc_hex} 0
Should Not Be In Log instruction set is not enabled for this CPU! PC: 0x${illegal_opcode_3_pc_hex} 0
Should Properly Handle ResetVector After Creation And After Reset 32
Create Machine bitness=32 init_pc=False
Should Properly Handle ResetVector At Init And After Reset
Should Properly Handle ResetVector After Creation And After Reset 64
Create Machine bitness=64 init_pc=False
Should Properly Handle ResetVector At Init And After Reset