Files
simulation_core/tests/unit-tests/bus-isolation.robot

207 lines
9.9 KiB
Plaintext

*** Variables ***
${CPU0_INITIATOR_STRING} the initiator 'cpu0'
${POSSIBLE_INITIATORS_STRING} peripherals implementing IPeripheralWithTransactionState (initiator not specified)
${SIMPLE_M33_REPL} SEPARATOR=\n
... """
... nvic: IRQControllers.NVIC @ sysbus new Bus.BusPointRegistration {
... ${SPACE*8}address: 0xE000E000;
... ${SPACE*8}cpu: cpu
... ${SPACE*4}}
... ${SPACE*4}-> cpu@0
... cpu: CPU.CortexM @ sysbus
... ${SPACE*4}cpuType: "cortex-m33"
... ${SPACE*4}nvic: nvic
... ${SPACE*4}cpuId: 0
... mem: Memory.ArrayMemory @ sysbus new Bus.BusPointRegistration { address: 0x10000; condition: "privileged && cpuSecure && attributionSecure"}
... ${SPACE*4}size: 0x1000
*** Keywords ***
Command Result Should Be Number
[Arguments] ${command} ${result}
${actual}= Execute Command ${command}
Should Be Equal As Numbers ${actual} ${result}
Create Bus Isolation Machine
Execute Script tests/unit-tests/bus_isolation.resc
Register With Condition And Expect Error
[Arguments] ${condition} ${error}
Run Keyword And Expect Error *${error}*
... Execute Command machine LoadPlatformDescriptionFromString "uart: UART.PL011 @ sysbus new Bus.BusPointRegistration { address: 0x0; condition: \\"${condition}\\" }"
Create Simple M33 Machine
[Arguments] ${enableTrustZone}=true
Execute Command mach create
Execute Command machine LoadPlatformDescriptionFromString ${SIMPLE_M33_REPL}\ncpu: { enableTrustZone: ${enableTrustZone} }"""
*** Test Cases ***
Should Handle Separation By State In Secure World
Create Bus Isolation Machine
Execute Command cpu0 Step 100
Register Should Be Equal 3 0x1010
Register Should Be Equal 4 0x2020
Register Should Be Equal 5 0x3030
Register Should Be Equal 6 0x4444
Register Should Be Equal 7 0x63707507
Register Should Be Equal 8 0x63707507
Register Should Be Equal 9 0x1010
Register Should Be Equal 10 0
Register Should Be Equal 11 0x3030
Register Should Be Equal 12 0x0404
Register Should Be Equal 1 0x63707506
Register Should Be Equal 2 0x63707506
Should Handle Separation By State In Nonsecure World
Create Bus Isolation Machine
Execute Command cpu0 SecureState false
Execute Command cpu0 Step 100
Register Should Be Equal 3 0
Register Should Be Equal 4 0
Register Should Be Equal 5 0x3030
Register Should Be Equal 6 0x4444
Register Should Be Equal 7 0x63707501
Register Should Be Equal 8 0x63707501
Register Should Be Equal 9 0x1010
Register Should Be Equal 10 0
Register Should Be Equal 11 0x3030
Register Should Be Equal 12 0x0404
Register Should Be Equal 1 0x63707500
Register Should Be Equal 2 0x63707500
Should Change Access Conditions At Runtime
Create Bus Isolation Machine
# Execute `ldr r0, =0x10000` and `ldr r3, [r0]` (the first iteration of the first read)
Execute Command cpu0 Step 2
Register Should Be Equal 3 0x1010 # Read OK because the condition in the repl is "(cpuSecure || !privileged) && initiator == cpu0"
Register Should Be Equal 4 0 # Not reached yet
# Now change the condition on the peripheral at 0x10000 to fail
Execute Command sysbus ChangePeripheralAccessCondition unpriv "initiator == cpu0 && (!cpuSecure || !privileged)"
# The next instruction is another `ldr r3, [r0]`, which will now see 0 (open bus)
Execute Command cpu0 Step
Register Should Be Equal 3 0 # Read 0 because the condition is now "(!cpuSecure || !privileged)" which fails
Register Should Be Equal 4 0 # Not reached yet
Should Read Through Privilege Aware Reader
Create Bus Isolation Machine
# ↓ raw initiator state which gets passed to the peripheral
Command Result Should Be Number reader Read 0x10010 0x00 0x72656100
Command Result Should Be Number reader Read 0x10010 0x01 0x72656101
Command Result Should Be Number reader Read 0x10010 0xa5 0x72656105
Command Result Should Be Number reader Read 0x20010 0x02 0x72656102
# Now we'll read some peripherals that have various conditions.
Command Result Should Be Number reader Read 0x10008 0x00 0x3030 # no condition
Command Result Should Be Number reader Read 0x10008 0x01 0x3030 # no condition
# condition: privileged and condition: !privileged, here decoded according to CortexM.StateBits,
# so it should only differ based on bit[0] of state
Command Result Should Be Number reader Read 0x1000c 0x00 0x0404
Command Result Should Be Number reader Read 0x1000c 0x01 0x4444
Command Result Should Be Number reader Read 0x1000c 0x02 0x0404
Command Result Should Be Number reader Read 0x1000c 0x03 0x4444
# condition: cpuSecure && privileged && initiator == cpu0, so we will not be able to read it even if the correct state
# (0x3) is specified
Command Result Should Be Number reader Read 0x10004 0x00 0
Command Result Should Be Number reader Read 0x10004 0x03 0
Should Handle Readers And Log Context Access
Create Bus Isolation Machine
Create Log Tester 1
Command Result Should Be Number reader Read 0x10010 0x00 0x72656100
Wait For Log Entry priv_aware: Read from context
Command Result Should Be Number reader2 Read 0x10010 0x00 0
Wait For Log Entry priv_aware: No context
Command Result Should Be Number reader3 Read 0x10010 0x00 0
Wait For Log Entry sysbus: ReadDoubleWord from non existing peripheral at 0x10010
Should Not Read Directly From Sysbus
Create Bus Isolation Machine
# Because priv_aware has a requirement that the initiator is cpu0 or reader, this will not work to access it
Command Result Should Be Number sysbus ReadDoubleWord 0x10010 0
# Because priv2_priv and priv2_unpriv have state requirements, this will not work to access either of them
Command Result Should Be Number sysbus ReadDoubleWord 0x1000c 0
# Because priv requires that the initiator is cpu0 in a specific state, this will not work either
Command Result Should Be Number sysbus ReadDoubleWord 0x10004 0
Test Unsupported Condition Without Initiator
Create Bus Isolation Machine
Register With Condition And Expect Error
... !invalid
... Provided condition is unsupported by ${POSSIBLE_INITIATORS_STRING}: invalid; supported conditions: 'privileged', 'cpuSecure', 'attributionSecure'
Test Unsupported Condition With Initiator
Create Bus Isolation Machine
Register With Condition And Expect Error
... invalid && initiator == cpu0
... Provided condition is unsupported by ${CPU0_INITIATOR_STRING}: invalid; supported conditions: 'privileged', 'cpuSecure', 'attributionSecure'
Test Condition With Initiator Not Supporting States
Create Bus Isolation Machine
Register With Condition And Expect Error
... cpuSecure && initiator == reader2 && !privileged
... Conditions provided (cpuSecure && !privileged) but the initiator 'reader2' doesn't implement IPeripheralWithTransactionState or has no state bits
Test Conditions With Unregistered Initiator
Execute Command mach create
Register With Condition And Expect Error
... cpuSecure && initiator == reader
... Invalid initiator: reader
Test Unregistered Initiator
Execute Command mach create
Register With Condition And Expect Error
... initiator == reader
... Invalid initiator: reader
Test Condition With No Initiators In The Machine
Execute Command mach create
Register With Condition And Expect Error
... !privileged
... Conditions provided (!privileged) but there are no peripherals implementing IPeripheralWithTransactionState or they have no common state bits
Test Conflicting Conditions
Create Bus Isolation Machine
Register With Condition And Expect Error
... cpuSecure && !cpuSecure
... Conditions conflict detected for ${POSSIBLE_INITIATORS_STRING}: cpuSecure
Should Access VTOR in Secure State
Create Simple M33 Machine
Execute Command sysbus.mem WriteDoubleWord 0x0 0x10100
Execute Command sysbus.mem WriteDoubleWord 0x4 0x10234
Execute Command sysbus.cpu VectorTableOffset 0x10000
Start Emulation
PC Should Be Equal 0x10234
Register Should Be Equal SP 0x10100
Should Access VTOR Without TrustZone Enabled
Create Simple M33 Machine enableTrustZone=false
Execute Command sysbus.mem WriteDoubleWord 0x0 0x10100
Execute Command sysbus.mem WriteDoubleWord 0x4 0x10234
Execute Command sysbus.cpu VectorTableOffset 0x10000
Start Emulation
PC Should Be Equal 0x10234
Register Should Be Equal SP 0x10100