ARM Cortex-A53 Cache Flush Ineffectiveness in EL3 Secure State
The core issue revolves around the inability to flush the data cache effectively when operating in the ARM Trusted Firmware (ATF) environment, specifically in the EL3 secure state. The user is working with a Hikey 620 board, utilizing ARM Trusted Firmware version 2.5, and has implemented a Secure Monitor Call (SMC) from a minimal barebone OS to ATF to flush the data cache. Despite using standard cache flushing mechanisms such as flush_dcache_range
and dcsw_op_all(DCCISW)
, the cache entries remain unaffected. This suggests a deeper architectural or implementation-level issue related to the ARM Cortex-A53 processor’s cache management in secure versus non-secure states.
The ARM Cortex-A53 processor, like many ARMv8-A cores, implements a multi-level cache hierarchy with separate instruction and data caches. These caches are tagged with security attributes, meaning that cache lines are associated with either secure or non-secure states. When operating in EL3 secure state, cache operations such as flushes or invalidations only affect cache lines tagged as secure. This behavior is by design to maintain isolation between secure and non-secure worlds, ensuring that secure data is not inadvertently exposed or corrupted by non-secure operations.
The user’s implementation attempts to flush the data cache while remaining in EL3 secure state, which inherently limits the scope of the cache operations to secure cache lines. This explains why the cache flushing procedures appear ineffective—non-secure cache lines, which may contain the data the user intends to flush, remain untouched. To address this, the cache flushing operation must be performed in a context where non-secure cache lines can be targeted, which requires transitioning to non-secure state within EL3.
Secure vs Non-Secure Cache Tagging and Execution State Mismatch
The root cause of the cache flush failure lies in the mismatch between the execution state (secure vs non-secure) and the cache tagging mechanism. In ARMv8-A architectures, the cache lines are tagged with a Non-Secure (NS) bit, which determines whether the cache line belongs to the secure or non-secure world. When the processor is in EL3 secure state, cache maintenance operations such as flushes or invalidations only apply to cache lines tagged as secure. This is a critical security feature to prevent secure data from being exposed or corrupted by non-secure operations.
The user’s implementation attempts to flush the data cache while remaining in EL3 secure state, which means that only secure cache lines are targeted. If the data to be flushed resides in non-secure cache lines, the flush operation will have no effect. This behavior is consistent with the ARM architecture’s design principles, which enforce strict separation between secure and non-secure worlds to maintain system integrity.
To flush non-secure cache lines, the processor must be in a state where non-secure cache operations are permitted. This can be achieved by temporarily switching to non-secure state within EL3. The Secure Configuration Register (SCR_EL3) controls the execution state of the processor, and setting the Non-Secure (NS) bit in SCR_EL3 allows the processor to perform cache operations on non-secure cache lines. However, this transition must be handled carefully to ensure that secure state integrity is maintained and that no secure data is exposed during the operation.
Implementing Secure-to-Non-Secure State Transition for Cache Flushing
To resolve the cache flush issue, the user must implement a secure-to-non-secure state transition within EL3 before performing the cache flush operation. This involves modifying the Secure Configuration Register (SCR_EL3) to set the Non-Secure (NS) bit, which allows the processor to target non-secure cache lines. The following steps outline the process:
-
Read and Modify SCR_EL3: The first step is to read the current value of SCR_EL3 and set the Non-Secure (NS) bit. This can be done using the
mrs
andmsr
instructions. Themrs
instruction reads the value of SCR_EL3 into a general-purpose register, and themsr
instruction writes the modified value back to SCR_EL3. Theorr
instruction is used to set the NS bit in the register. -
Insert an Instruction Synchronization Barrier (ISB): After modifying SCR_EL3, an Instruction Synchronization Barrier (ISB) must be executed to ensure that the change takes effect immediately. The ISB flushes the processor’s pipeline, ensuring that all subsequent instructions are executed in the new execution state.
-
Perform Cache Flush Operations: With the processor now in non-secure state, the cache flush operations can be performed. The
dcsw_op_all(DCCISW)
instruction can be used to flush the data cache. This instruction invalidates all cache lines in the data cache, ensuring that any dirty data is written back to memory and the cache lines are cleared. -
Restore Secure State: After completing the cache flush operations, the processor must be returned to secure state to maintain system security. This involves clearing the Non-Secure (NS) bit in SCR_EL3 and executing another ISB to ensure the change takes effect.
The following code snippet demonstrates the implementation of the secure-to-non-secure state transition and cache flush operation:
// Read SCR_EL3 and set the Non-Secure (NS) bit
mrs x0, SCR_EL3
orr x1, x0, #SCR_EL3_NS
msr SCR_EL3, x1
isb
// Perform cache flush operations
dcsw_op_all(DCCISW)
// Restore secure state by clearing the Non-Secure (NS) bit
mrs x0, SCR_EL3
bic x1, x0, #SCR_EL3_NS
msr SCR_EL3, x1
isb
This sequence ensures that the cache flush operation targets non-secure cache lines, effectively clearing the data cache as intended. The use of ISB instructions guarantees that the state transitions are handled correctly, preventing any potential race conditions or inconsistencies in the processor’s execution state.
In conclusion, the cache flush failure in EL3 secure state is a direct consequence of the ARM architecture’s security mechanisms, which restrict cache operations to secure cache lines when in secure state. By implementing a secure-to-non-secure state transition within EL3, the user can perform cache flush operations on non-secure cache lines, resolving the issue and ensuring that the data cache is properly managed. This approach maintains the integrity of the secure state while allowing necessary cache maintenance operations to be performed.