ARM Cortex-M33 NOCP Usage Fault During WIC Sleep and Wake-Up
The ARM Cortex-M33 processor, with its TrustZone security extension, introduces a complex interplay between secure and non-secure states, particularly when dealing with the Floating-Point Unit (FPU). A common issue arises when a non-secure thread enters Wait-for-Interrupt (WIC) sleep mode, and a secure handler subsequently wakes the processor. In this scenario, a No Coprocessor (NOCP) Usage Fault is triggered, even when no explicit FPU instructions are executed in the non-secure code. This fault is indicative of a misconfiguration in the FPU context management between secure and non-secure states.
The root of the problem lies in the handling of the FPU context during state transitions. The Cortex-M33’s FPU is shared between secure and non-secure worlds, and its state must be carefully managed to avoid faults. Specifically, the FPU context is preserved and restored during context switches, but the configuration of the Non-Secure Access Control Register (NSACR) and the Floating-Point Context Control Register (FPCCR) plays a critical role in determining whether the FPU can be accessed without triggering a fault.
When the non-secure thread enters WIC sleep, the processor saves the FPU context if the FPU was active (indicated by the CONTROL.FPCA bit). Upon waking, the secure handler may attempt to restore the FPU context, but if the NSACR.CP10 bit is not set to allow non-secure access to the FPU, a NOCP Usage Fault is generated. This fault occurs because the processor attempts to access the FPU in a non-secure context without the necessary permissions.
NSACR.CP10 and FPCCR.ASPEN Configuration Mismatch
The NOCP Usage Fault is directly related to the configuration of two key registers: the Non-Secure Access Control Register (NSACR) and the Floating-Point Context Control Register (FPCCR). The NSACR.CP10 bit controls whether non-secure software can access the FPU, while the FPCCR.ASPEN bit determines whether the FPU context is automatically saved and restored during context switches.
In the case where NSACR.CP10 is set to 0, non-secure access to the FPU is prohibited, and any attempt to access the FPU in a non-secure context will result in a NOCP Usage Fault. This is true even if the FPU was not explicitly used in the non-secure code. The fault occurs because the processor attempts to restore the FPU context upon waking from WIC sleep, and the lack of permission to access the FPU in the non-secure state triggers the fault.
The FPCCR.ASPEN bit further complicates the issue. When ASPEN is set to 1, the FPU context is automatically saved and restored during context switches, and the CONTROL.FPCA bit is set to 1 when an FPU instruction is executed. If ASPEN is set to 0, the FPU context is not automatically managed, and the CONTROL.FPCA bit remains 0, effectively disabling the FPU. This configuration can prevent the NOCP Usage Fault, but it also means that the FPU context is not preserved across context switches, which may not be desirable in all scenarios.
The interaction between NSACR.CP10 and FPCCR.ASPEN is critical. If NSACR.CP10 is set to 0 and FPCCR.ASPEN is set to 1, the processor will attempt to save and restore the FPU context, but the lack of permission to access the FPU in the non-secure state will result in a NOCP Usage Fault. Conversely, if NSACR.CP10 is set to 1, non-secure access to the FPU is permitted, and the fault is avoided. Similarly, if FPCCR.ASPEN is set to 0, the FPU context is not managed, and the fault is avoided, but at the cost of losing the FPU context across context switches.
Configuring NSACR.CP10 and FPCCR.ASPEN for Secure-Non-Secure FPU Sharing
To resolve the NOCP Usage Fault and ensure proper FPU context management between secure and non-secure states, the NSACR.CP10 and FPCCR.ASPEN bits must be configured appropriately. The following steps outline the necessary configurations and their implications:
-
Enable Non-Secure Access to the FPU (NSACR.CP10 = 1): Setting NSACR.CP10 to 1 allows non-secure software to access the FPU. This configuration is necessary if the non-secure code is expected to use the FPU or if the FPU context needs to be preserved across context switches. When NSACR.CP10 is set to 1, the processor will not generate a NOCP Usage Fault when attempting to access the FPU in a non-secure context.
-
Disable Automatic FPU Context Management (FPCCR.ASPEN = 0): Setting FPCCR.ASPEN to 0 disables the automatic saving and restoring of the FPU context during context switches. This configuration prevents the processor from attempting to access the FPU in a non-secure context, thereby avoiding the NOCP Usage Fault. However, this also means that the FPU context is not preserved across context switches, which may not be suitable for all applications.
-
Enable Automatic FPU Context Management (FPCCR.ASPEN = 1): If the FPU context needs to be preserved across context switches, FPCCR.ASPEN should be set to 1. In this case, NSACR.CP10 must also be set to 1 to allow non-secure access to the FPU. This configuration ensures that the FPU context is automatically saved and restored, and the NOCP Usage Fault is avoided.
-
Combining NSACR.CP10 and FPCCR.ASPEN Configurations: The following table summarizes the possible configurations of NSACR.CP10 and FPCCR.ASPEN and their effects:
NSACR.CP10 | FPCCR.ASPEN | Result |
---|---|---|
0 | 1 | NOCP Usage Fault (Non-secure access to FPU prohibited) |
0 | 0 | No Fault (FPU context not managed) |
1 | 1 | No Fault (FPU context managed, non-secure access allowed) |
1 | 0 | No Fault (FPU context not managed, non-secure access allowed) |
-
Handling FPU Context in Secure Handlers: When a secure handler wakes the processor from WIC sleep, it must ensure that the FPU context is properly restored if FPCCR.ASPEN is set to 1. This involves checking the CONTROL.FPCA bit to determine if the FPU was active before the sleep mode was entered. If CONTROL.FPCA is set to 1, the secure handler must restore the FPU context before returning to the non-secure state.
-
Testing and Validation: After configuring NSACR.CP10 and FPCCR.ASPEN, it is essential to thoroughly test the system to ensure that the NOCP Usage Fault is avoided and that the FPU context is correctly managed across secure and non-secure state transitions. This includes testing scenarios where the non-secure code uses the FPU, as well as scenarios where the FPU is not used but the processor enters and exits WIC sleep mode.
By carefully configuring NSACR.CP10 and FPCCR.ASPEN, developers can avoid the NOCP Usage Fault and ensure proper FPU context management in systems that use the ARM Cortex-M33’s TrustZone security extension. This configuration is critical for applications that require both secure and non-secure access to the FPU, particularly in scenarios involving low-power modes and context switching.