ARM Cortex-M23 Secure and Non-Secure State Transition Issues

The Nuvoton M2351 microcontroller, based on the ARM Cortex-M23 processor, is designed to support ARMv8-M security extensions, which include TrustZone for Armv8-M. TrustZone introduces the concept of Secure and Non-Secure states, allowing developers to partition their software into secure and non-secure domains. This partitioning is crucial for applications that require robust security, such as IoT devices, where sensitive data and critical operations must be protected from unauthorized access.

In the context of the Nuvoton M2351, the issue arises during the initialization of the Keil RTX5 real-time operating system (RTOS). Specifically, a Hard Fault is triggered when the osKernelInitialize() function is called from the Non-Secure main function. The Hard Fault occurs precisely when the TZ_InitContextSystem_S() function is invoked. This function is part of the TrustZone initialization process, which is responsible for setting up the context switching between Secure and Non-Secure states.

The Hard Fault is particularly perplexing because the code appears to branch to a valid address (0x10044150) within the Non-Secure memory space. However, instead of executing the instructions at this address, the processor immediately jumps to the Hard Fault Handler. This behavior suggests that there is a fundamental issue with the way the Secure and Non-Secure states are being managed during the transition.

The Cortex-M23 processor enforces strict rules for transitioning between Secure and Non-Secure states. When a Non-Secure function attempts to call a Secure function, the processor must ensure that the call is legitimate and that the Secure function is properly marked as Non-Secure Callable (NSC). This is achieved through the use of the Secure Gateway (SG) instruction, which must be the first instruction in any Secure function that can be called from the Non-Secure state. If the SG instruction is missing or incorrectly placed, the processor will trigger a Hard Fault to prevent unauthorized access to Secure resources.

In this case, the Hard Fault is likely caused by the absence of proper configuration of the Security Attribution Unit (SAU). The SAU is responsible for defining the memory regions that are Secure, Non-Secure, or Non-Secure Callable. If the SAU is not properly configured, the memory region containing the TZ_InitContextSystem_S() function may not be marked as Non-Secure Callable, leading to the Hard Fault when the function is called from the Non-Secure state.

SAU Configuration and Non-Secure Callable Memory Regions

The Security Attribution Unit (SAU) is a critical component of the ARM Cortex-M23 processor’s TrustZone implementation. The SAU allows developers to define memory regions and assign them specific security attributes, such as Secure, Non-Secure, or Non-Secure Callable. These attributes determine how the processor handles access to these regions, particularly when transitioning between Secure and Non-Secure states.

In the context of the Nuvoton M2351 and the Keil RTX5 RTOS, the SAU must be properly configured to ensure that the TZ_InitContextSystem_S() function and other related functions are marked as Non-Secure Callable. This is essential because these functions are called from the Non-Secure state during the RTOS initialization process. If the SAU is not configured correctly, the processor will treat these functions as Secure-only, and any attempt to call them from the Non-Secure state will result in a Hard Fault.

The SAU configuration is typically done during the early stages of the system initialization, often in the startup code or the Secure firmware. The SAU configuration involves setting up the SAU regions, which are defined by their base address, size, and security attributes. Each SAU region can be configured as Secure, Non-Secure, or Non-Secure Callable. The Non-Secure Callable attribute is particularly important for functions that need to be called from the Non-Secure state, as it allows the processor to transition to the Secure state in a controlled manner.

In the case of the Nuvoton M2351, the SAU configuration must include a region that covers the memory space where the TZ_InitContextSystem_S() function is located. This region must be marked as Non-Secure Callable to allow the Non-Secure code to call the function without triggering a Hard Fault. If this region is not defined or is incorrectly configured, the processor will treat the function as Secure-only, and the call from the Non-Secure state will be blocked, resulting in a Hard Fault.

The SAU configuration is not the only factor that can cause issues with Secure and Non-Secure state transitions. The placement of the Secure Gateway (SG) instruction within the Secure function is also critical. The SG instruction must be the first instruction in any Secure function that is intended to be called from the Non-Secure state. This instruction signals to the processor that the function is a valid entry point for Secure code and allows the processor to transition to the Secure state safely. If the SG instruction is missing or incorrectly placed, the processor will trigger a Hard Fault to prevent unauthorized access to Secure resources.

In the case of the Nuvoton M2351, the TZ_InitContextSystem_S() function must include the SG instruction as its first instruction. This ensures that the function can be called from the Non-Secure state without triggering a Hard Fault. If the SG instruction is missing or incorrectly placed, the processor will treat the function as Secure-only, and the call from the Non-Secure state will be blocked, resulting in a Hard Fault.

Implementing Proper SAU Configuration and Secure Gateway Instructions

To resolve the Hard Fault issue on the Nuvoton M2351 during RTX5 kernel initialization, it is essential to implement proper SAU configuration and ensure that the Secure Gateway (SG) instruction is correctly placed within the Secure functions. This involves several steps, including defining the SAU regions, marking the appropriate memory regions as Non-Secure Callable, and verifying the placement of the SG instruction in the Secure functions.

The first step in resolving the issue is to define the SAU regions correctly. This involves identifying the memory regions that contain the Secure functions that need to be called from the Non-Secure state, such as the TZ_InitContextSystem_S() function. These regions must be marked as Non-Secure Callable in the SAU configuration. The SAU configuration is typically done in the startup code or the Secure firmware, and it involves setting up the SAU regions with the appropriate base address, size, and security attributes.

For example, if the TZ_InitContextSystem_S() function is located in a memory region starting at address 0x000008f0, the SAU configuration must include a region that covers this address range and is marked as Non-Secure Callable. This can be done using the following code snippet:

// Define the SAU region for the TZ_InitContextSystem_S function
SAU->RNR = 0; // Select SAU region 0
SAU->RBAR = 0x000008f0; // Base address of the region
SAU->RLAR = 0x000008ff | (1 << 0); // Limit address and enable the region
SAU->RLAR |= (1 << 1); // Mark the region as Non-Secure Callable

This code snippet defines an SAU region that covers the memory range from 0x000008f0 to 0x000008ff and marks it as Non-Secure Callable. This ensures that the TZ_InitContextSystem_S() function can be called from the Non-Secure state without triggering a Hard Fault.

The next step is to ensure that the Secure Gateway (SG) instruction is correctly placed within the Secure functions. The SG instruction must be the first instruction in any Secure function that is intended to be called from the Non-Secure state. This instruction signals to the processor that the function is a valid entry point for Secure code and allows the processor to transition to the Secure state safely.

In the case of the TZ_InitContextSystem_S() function, the SG instruction must be the first instruction in the function. This can be done using the following assembly code:

TZ_InitContextSystem_S:
    SG          ; Secure Gateway instruction
    ; Rest of the function code
    BX lr       ; Return from the function

This assembly code ensures that the TZ_InitContextSystem_S() function includes the SG instruction as its first instruction, allowing it to be called from the Non-Secure state without triggering a Hard Fault.

Once the SAU configuration and the SG instruction placement have been verified, the next step is to test the system to ensure that the Hard Fault issue has been resolved. This involves running the RTX5 kernel initialization code and verifying that the osKernelInitialize() function completes successfully without triggering a Hard Fault. If the Hard Fault issue persists, it may be necessary to review the SAU configuration and the SG instruction placement to ensure that they are correct.

In addition to the SAU configuration and the SG instruction placement, it is also important to consider other factors that could contribute to the Hard Fault issue. For example, the stack usage in the Secure and Non-Secure states must be carefully managed to ensure that there is no stack corruption during the state transition. The stack pointers for the Secure and Non-Secure states must be properly initialized, and the stack sizes must be sufficient to handle the function calls and context switches.

Another factor to consider is the alignment of the memory regions. The ARM Cortex-M23 processor requires that certain memory regions, such as the SAU regions, are aligned to specific boundaries. If the memory regions are not properly aligned, the processor may trigger a Hard Fault or other unexpected behavior. It is important to ensure that the SAU regions are aligned to the required boundaries and that the memory layout is consistent with the processor’s requirements.

In conclusion, the Hard Fault issue on the Nuvoton M2351 during RTX5 kernel initialization is caused by improper SAU configuration and the absence of the Secure Gateway (SG) instruction in the Secure functions. To resolve this issue, it is essential to define the SAU regions correctly, mark the appropriate memory regions as Non-Secure Callable, and ensure that the SG instruction is correctly placed within the Secure functions. By following these steps, the Hard Fault issue can be resolved, and the RTX5 kernel initialization can proceed successfully.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *