PendSV Exception Banking and Secure State Context Switching
The PendSV (Pendable Service Call) exception in ARMv8-M architecture is a critical mechanism for implementing context switching in real-time operating systems (RTOS). It is particularly useful for deferring context switching until higher-priority interrupts have completed, ensuring deterministic behavior in embedded systems. However, the introduction of the ARMv8-M security extension, which divides the processor into Secure and Non-secure states, adds complexity to the handling of PendSV exceptions.
In ARMv8-M, the PendSV exception is banked between Secure and Non-secure states. This means that there are separate PendSV exception handlers for each state, and the processor must ensure that the correct handler is invoked based on the security state of the executing code. The Secure state is typically used for handling sensitive operations, such as cryptographic functions or secure boot, while the Non-secure state handles general application code.
The challenge arises when an RTOS running in the Non-secure state needs to trigger a PendSV exception that involves both Secure and Non-secure operations. For example, a Non-secure RTOS might need to perform a context switch that also involves updating secure counters or logging secure events. In such cases, the RTOS must ensure that the PendSV exception is handled in the Secure state before returning to the Non-secure state to complete the context switch.
The ARMv8-M architecture provides mechanisms to manage the priority and execution of Secure and Non-secure exceptions. The Application Interrupt and Reset Control Register (AIRCR) includes the PRIS (Priority for Secure Exceptions) bit, which can be set to ensure that Secure exceptions always have higher priority than Non-secure exceptions. This ensures that when a PendSV exception is pended, the Secure handler is executed first if the PRIS bit is set. However, this also requires careful management of exception priorities and the use of memory barriers to ensure proper synchronization between Secure and Non-secure states.
PRIS Bit Configuration and Exception Priority Management
One of the key factors influencing the behavior of PendSV exceptions in ARMv8-M is the configuration of the PRIS bit in the AIRCR register. The PRIS bit determines whether Secure exceptions have higher priority than Non-secure exceptions. When the PRIS bit is set, Secure exceptions are given precedence, ensuring that Secure PendSV handlers are executed before Non-secure PendSV handlers. This is particularly important in systems where Secure operations must be completed before returning to Non-secure operations.
However, the use of the PRIS bit must be carefully managed to avoid unintended side effects. For example, setting the PRIS bit can lead to increased latency for Non-secure exceptions, as they will always be preempted by Secure exceptions. This can be problematic in real-time systems where deterministic timing is critical. Additionally, the PRIS bit affects all exceptions, not just PendSV, so its configuration must be considered in the context of the entire exception handling system.
Another consideration is the interaction between the PRIS bit and the Secure Attribution Unit (SAU). The SAU is used to define memory regions as Secure or Non-secure, and it plays a crucial role in determining the security state of exception handlers. For example, if a PendSV handler is located in a Secure memory region, the SAU must be configured to allow Non-secure code to call the Secure handler. This involves setting the appropriate bits in the SAU Region Limit Address Register (RLAR) to mark the region as Non-secure callable.
The configuration of the SAU and the PRIS bit must be coordinated to ensure that PendSV exceptions are handled correctly. For example, if the PRIS bit is set but the SAU is not configured to allow Non-secure calls to the Secure PendSV handler, the system may enter a deadlock or undefined state. Similarly, if the SAU is configured incorrectly, the Secure PendSV handler may not be accessible from the Non-secure state, leading to system failures.
Implementing Secure and Non-secure PendSV Handlers with AIRCR and SAU
To implement a system where PendSV exceptions are handled in both Secure and Non-secure states, the following steps must be taken:
First, the PRIS bit in the AIRCR register must be set to ensure that Secure exceptions have higher priority than Non-secure exceptions. This can be done by writing to the AIRCR register with the appropriate bit set. For example, the following code snippet sets the PRIS bit:
AIRCR = AIRCR | (1 << 2); // Set PRIS bit
Next, the SAU must be configured to define the memory regions for Secure and Non-secure code. This involves writing to the SAU Region Number Register (RNR), SAU Region Base Address Register (RBAR), and SAU Region Limit Address Register (RLAR). The following code snippet demonstrates how to configure a Secure memory region that is Non-secure callable:
SAU_RNR = 0x1; // Select region 1
SAU_RBAR = 0x20000000; // Set base address for region 1
SAU_RLAR = 0x2000FFFF | (1 << 1); // Set limit address and mark as Non-secure callable
Once the SAU is configured, the Secure PendSV handler must be implemented to handle Secure operations. This handler should be designed to perform the necessary Secure tasks and then return control to the Non-secure PendSV handler. The following code snippet shows an example of a Secure PendSV handler:
void Secure_PendSV_Handler(void) {
// Perform Secure operations
// ...
// Return to Non-secure state
__DSB(); // Data Synchronization Barrier
__ISB(); // Instruction Synchronization Barrier
}
Finally, the Non-secure PendSV handler must be implemented to handle the normal context switching tasks. This handler should be designed to resume execution after the Secure PendSV handler has completed. The following code snippet shows an example of a Non-secure PendSV handler:
void NonSecure_PendSV_Handler(void) {
// Perform context switching
// ...
// Resume normal execution
__DSB(); // Data Synchronization Barrier
__ISB(); // Instruction Synchronization Barrier
}
In addition to the above steps, it is important to use memory barriers to ensure proper synchronization between Secure and Non-secure states. The Data Synchronization Barrier (DSB) and Instruction Synchronization Barrier (ISB) instructions are used to ensure that all memory accesses and instructions are completed before proceeding to the next state. This is particularly important when transitioning between Secure and Non-secure states, as the processor must ensure that all pending operations are completed before changing states.
By following these steps and carefully managing the configuration of the PRIS bit and SAU, it is possible to implement a system where PendSV exceptions are handled in both Secure and Non-secure states. This allows for the integration of Secure operations into the context switching process, enabling the development of secure and reliable embedded systems.
Conclusion
The handling of PendSV exceptions in ARMv8-M architecture requires careful consideration of the security state and the interaction between Secure and Non-secure code. By configuring the PRIS bit in the AIRCR register and the SAU, it is possible to ensure that Secure PendSV handlers are executed before Non-secure handlers, allowing for the integration of Secure operations into the context switching process. However, this requires careful management of exception priorities and the use of memory barriers to ensure proper synchronization between Secure and Non-secure states. By following the steps outlined in this guide, developers can implement secure and reliable context switching in ARMv8-M systems.