Skip to content

Commit fee4f63

Browse files
committed
Added the PMSAv8-R region setup and fault handler for the module port
Two of the module manager's port-specific sources, both derived from the Armv8-M versions for the reasons given in the previous commit. The region setup needed two substantive changes and they are the ones worth reviewing. The address mask is 64-byte where Armv8-M is 32-byte, and it is now a named constant, TXM_MODULE_MPU_ADDRESS_MASK, rather than a literal repeated six times. PRBAR and PRLAR hold attributes in the bits below the granule, so masking to the wrong boundary does not fault: it writes address bits into the shareability and permission fields, and the region comes up with attributes nobody asked for. That failure is silent, which is why the constant is named and the reason is recorded where the code uses it. Regions are non-shareable where the M33 port marks module memory inner-shareable. The RTU here is a single Cortex-R52 and every region in the board support package's map is non-shareable, so matching it keeps one memory model across the kernel and its modules. A multi-core RTU configuration would need to revisit this, and much else besides. The fault handler needed almost nothing, which was worth finding out. It is architecture-neutral: it terminates the faulting thread and calls the notification callback. The register capture happens before it, in the abort vector, and that part is still to be written -- DFSR, DFAR, IFSR and IFAR have to be read before anything else can fault and overwrite them, and on this core the abort is taken in Abort mode with its own banked lr and sp, so the capture belongs there rather than in C. The file now says so, so the next person does not look for it here. Both files compile clean against the module headers, which also confirms the header work: the new mask and the DFSR, DFAR, IFSR and IFAR fault fields all resolve. Assisted-by: Claude Code (Opus 5) <noreply@anthropic.com>
1 parent 3294dd3 commit fee4f63

3 files changed

Lines changed: 329 additions & 0 deletions

File tree

‎ports_module/cortex_r52/gnu/inc/txm_module_port.h‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ DATA WBWA RA : 0b [Outer]1111 [Inner]1111
205205
permissions of the region instead. */
206206
#define TXM_MODULE_MPU_ALIGNMENT 64
207207

208+
/* Mask that keeps only the address bits of PRBAR and PRLAR. The low six bits
209+
hold attributes on this core, so every base and limit written into the region
210+
table must be masked with this and not with the Armv8-M 32-byte equivalent. */
211+
212+
#define TXM_MODULE_MPU_ADDRESS_MASK 0xFFFFFFC0
213+
208214
/* No secure-stack extension calls. Those are the Armv8-M security extension,
209215
which this core does not have: privilege here is the ARM mode, EL1 against
210216
EL0, and there is no secure world to allocate a second stack in. */
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/***************************************************************************
2+
* Copyright (c) 2024 Microsoft Corporation
3+
* Copyright (c) 2026-present Eclipse ThreadX contributors
4+
*
5+
* This program and the accompanying materials are made available under the
6+
* terms of the MIT License which is available at
7+
* https://opensource.org/licenses/MIT.
8+
*
9+
* SPDX-License-Identifier: MIT
10+
**************************************************************************/
11+
12+
13+
/**************************************************************************/
14+
/**************************************************************************/
15+
/** */
16+
/** ThreadX Component */
17+
/** */
18+
/** Module Manager */
19+
/** */
20+
/**************************************************************************/
21+
/**************************************************************************/
22+
23+
#define TX_SOURCE_CODE
24+
25+
#include "tx_api.h"
26+
#include "tx_thread.h"
27+
#include "txm_module.h"
28+
29+
30+
/* This handler is architecture-neutral: it terminates the faulting thread and
31+
calls the notification callback. The fault registers are captured before it
32+
runs, in the abort vector, because DFSR, DFAR, IFSR and IFAR must be read
33+
before anything else can fault and overwrite them -- and on this core the
34+
abort is taken in Abort mode with its own banked lr and sp, so the capture has
35+
to happen there rather than here.
36+
37+
Data aborts and prefetch aborts both arrive here. A module can violate its
38+
protection either way: writing outside its data region, or branching outside
39+
its code region. Which pair of registers is meaningful depends on which it
40+
was, and the fault info structure carries both. */
41+
42+
/* Define the user's fault notification callback function pointer. This is
43+
setup via the txm_module_manager_memory_fault_notify API. */
44+
45+
VOID (*_txm_module_manager_fault_notify)(TX_THREAD *, TXM_MODULE_INSTANCE *);
46+
47+
48+
/* Define a macro that can be used to allocate global variables useful to
49+
store information about the last fault. This macro is defined in
50+
txm_module_port.h and is usually populated in the assembly language
51+
fault handling prior to the code calling _txm_module_manager_memory_fault_handler. */
52+
53+
TXM_MODULE_MANAGER_FAULT_INFO
54+
55+
56+
/**************************************************************************/
57+
/* */
58+
/* FUNCTION RELEASE */
59+
/* */
60+
/* _txm_module_manager_memory_fault_handler Cortex-R52 */
61+
/* 6.1.8 */
62+
/* AUTHOR */
63+
/* */
64+
/* Scott Larson, Microsoft Corporation */
65+
/* */
66+
/* DESCRIPTION */
67+
/* */
68+
/* This function handles a fault associated with a memory protected */
69+
/* module. */
70+
/* */
71+
/* INPUT */
72+
/* */
73+
/* None */
74+
/* */
75+
/* OUTPUT */
76+
/* */
77+
/* None */
78+
/* */
79+
/* CALLS */
80+
/* */
81+
/* _tx_thread_terminate Terminate thread */
82+
/* */
83+
/* CALLED BY */
84+
/* */
85+
/* Fault handler */
86+
/* */
87+
/**************************************************************************/
88+
VOID _txm_module_manager_memory_fault_handler(VOID)
89+
{
90+
91+
TXM_MODULE_INSTANCE *module_instance_ptr;
92+
TX_THREAD *thread_ptr;
93+
94+
/* Pickup the current thread. */
95+
thread_ptr = _tx_thread_current_ptr;
96+
97+
/* Initialize the module instance pointer to NULL. */
98+
module_instance_ptr = TX_NULL;
99+
100+
/* Is there a thread? */
101+
if (thread_ptr)
102+
{
103+
/* Pickup the module instance. */
104+
module_instance_ptr = thread_ptr -> tx_thread_module_instance_ptr;
105+
106+
/* Terminate the current thread. */
107+
_tx_thread_terminate(_tx_thread_current_ptr);
108+
}
109+
110+
/* Determine if there is a user memory fault notification callback. */
111+
if (_txm_module_manager_fault_notify)
112+
{
113+
/* Yes, call the user's notification memory fault callback. */
114+
(_txm_module_manager_fault_notify)(thread_ptr, module_instance_ptr);
115+
}
116+
}

0 commit comments

Comments
 (0)