summaryrefslogtreecommitdiff
path: root/ports_module
diff options
context:
space:
mode:
Diffstat (limited to 'ports_module')
-rw-r--r--ports_module/cortex_a7/ac5/example_build/build_threadx_demo.bat3
-rw-r--r--ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S16
-rw-r--r--ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S16
-rw-r--r--ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S16
-rw-r--r--ports_module/cortex_m23/ac6/inc/tx_port.h10
-rw-r--r--ports_module/cortex_m23/ac6/inc/txm_module_port.h2
-rw-r--r--ports_module/cortex_m23/ac6/module_lib/src/txm_module_thread_shell_entry.c2
-rw-r--r--ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S14
-rw-r--r--ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c225
-rw-r--r--ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack_initialize.S10
-rw-r--r--ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m23/gnu/inc/tx_port.h10
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S14
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c221
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack_initialize.S (renamed from ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_notify.c)75
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_notify.c96
-rw-r--r--ports_module/cortex_m23/iar/inc/tx_port.h10
-rw-r--r--ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s14
-rw-r--r--ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c229
-rw-r--r--ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack_initialize.s (renamed from ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_notify.c)72
-rw-r--r--ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m3/ac5/inc/txm_module_port.h59
-rw-r--r--ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s51
-rw-r--r--ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m3/ac6/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m3/ac6/module_lib/src/txm_module_thread_shell_entry.c2
-rw-r--r--ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S36
-rw-r--r--ports_module/cortex_m3/ac6/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m3/gnu/example_build/build_threadx_sample.bat4
-rw-r--r--ports_module/cortex_m3/gnu/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S52
-rw-r--r--ports_module/cortex_m3/gnu/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m3/iar/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s53
-rw-r--r--ports_module/cortex_m3/iar/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m33/ac6/inc/tx_port.h19
-rw-r--r--ports_module/cortex_m33/ac6/module_lib/src/txm_module_thread_shell_entry.c2
-rw-r--r--ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S12
-rw-r--r--ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack.c218
-rw-r--r--ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack_initialize.S10
-rw-r--r--ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m33/gnu/inc/tx_port.h19
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S12
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack.c221
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack_initialize.S8
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_notify.c96
-rw-r--r--ports_module/cortex_m33/iar/inc/tx_port.h19
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s12
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack.c224
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack_initialize.s (renamed from ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_notify.c)72
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_handler.c93
-rw-r--r--ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_notify.c96
-rw-r--r--ports_module/cortex_m4/ac5/inc/txm_module_port.h59
-rw-r--r--ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s51
-rw-r--r--ports_module/cortex_m4/ac5/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m4/ac6/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m4/ac6/module_lib/src/txm_module_thread_shell_entry.c2
-rw-r--r--ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S36
-rw-r--r--ports_module/cortex_m4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m4/gnu/example_build/build_threadx_sample.bat5
-rw-r--r--ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S127
-rw-r--r--ports_module/cortex_m4/gnu/example_build/cortexm_vectors.S77
-rw-r--r--ports_module/cortex_m4/gnu/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S52
-rw-r--r--ports_module/cortex_m4/gnu/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m4/iar/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s53
-rw-r--r--ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m7/ac5/inc/txm_module_port.h59
-rw-r--r--ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s51
-rw-r--r--ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m7/ac6/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c2
-rw-r--r--ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S36
-rw-r--r--ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m7/gnu/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S52
-rw-r--r--ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_m7/iar/inc/txm_module_port.h61
-rw-r--r--ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s53
-rw-r--r--ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c71
-rw-r--r--ports_module/cortex_r4/ac6/example_build/sample_threadx/.cproject170
-rw-r--r--ports_module/cortex_r4/ac6/example_build/sample_threadx/.project26
-rw-r--r--ports_module/cortex_r4/ac6/example_build/sample_threadx/sample_threadx.c374
-rw-r--r--ports_module/cortex_r4/ac6/example_build/sample_threadx/tx_cortex_r4.launch469
87 files changed, 4160 insertions, 1905 deletions
diff --git a/ports_module/cortex_a7/ac5/example_build/build_threadx_demo.bat b/ports_module/cortex_a7/ac5/example_build/build_threadx_demo.bat
new file mode 100644
index 00000000..032a2195
--- /dev/null
+++ b/ports_module/cortex_a7/ac5/example_build/build_threadx_demo.bat
@@ -0,0 +1,3 @@
+armasm -g --cpu=cortex-a7.no_neon --fpu=softvfp --apcs=interwork tx_initialize_low_level.s
+armcc -g --cpu=cortex-a7.no_neon --fpu=softvfp -c -I../inc -I../../../../common/inc sample_threadx.c
+armlink -d -o sample_threadx_module_manager.axf --elf --ro 0x80000000 --first tx_initialize_low_level.o(VECTORS) --remove --map --symbols --list sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a
diff --git a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
index 8ccb9f7a..0e0c8f67 100644
--- a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -65,6 +65,9 @@
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -345,17 +348,6 @@ __tx_ts_restore:
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- MOVS r6, #0x10
- BICS r2, r2, r6 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
index f1f5872b..7e613c25 100644
--- a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -65,6 +65,9 @@
/* 01-31-2022 Scott Larson Initial Version 6.1.10 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -345,17 +348,6 @@ __tx_ts_restore:
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- MOVS r6, #0x10
- BICS r2, r2, r6 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
index bc498210..af30dffa 100644
--- a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S
@@ -36,7 +36,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M0+/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -72,6 +72,9 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* change handler name, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -330,17 +333,6 @@ __tx_ts_restore:
CMP r2, #0
BEQ skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- MOVS r6, #0x10
- BICS r2, r2, r6 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m23/ac6/inc/tx_port.h b/ports_module/cortex_m23/ac6/inc/tx_port.h
index b3c3d99b..ae6e2c50 100644
--- a/ports_module/cortex_m23/ac6/inc/tx_port.h
+++ b/ports_module/cortex_m23/ac6/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -51,6 +51,10 @@
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -507,7 +511,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -573,7 +577,7 @@ unsigned int was_masked;
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1.11 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/AC6 Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m23/ac6/inc/txm_module_port.h b/ports_module/cortex_m23/ac6/inc/txm_module_port.h
index ec009327..72bc525b 100644
--- a/ports_module/cortex_m23/ac6/inc/txm_module_port.h
+++ b/ports_module/cortex_m23/ac6/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M23/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m23/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m23/ac6/module_lib/src/txm_module_thread_shell_entry.c
index ca2a267d..6f4451b0 100644
--- a/ports_module/cortex_m23/ac6/module_lib/src/txm_module_thread_shell_entry.c
+++ b/ports_module/cortex_m23/ac6/module_lib/src/txm_module_thread_shell_entry.c
@@ -58,7 +58,7 @@ extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-M23/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
index 09d4658f..69e8a192 100644
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -65,6 +65,9 @@
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -379,15 +382,6 @@ _skip_secure_restore:
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c
index 8941a705..f1096762 100644
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -45,8 +45,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -54,8 +60,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -63,7 +75,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M23/AC6 */
-/* 6.1.8 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -98,16 +110,20 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Modified comment(s), and */
+/* 06-02-2021 Scott Larson Modified comment(s), and */
/* changed name, execute in */
/* handler mode, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_initialize(void)
{
UINT status;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
@@ -118,12 +134,26 @@ UINT status;
{
/* Set secure mode to use PSP. */
__set_CONTROL(__get_CONTROL() | 2);
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -136,7 +166,7 @@ UINT status;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M23/AC6 */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -160,9 +190,7 @@ UINT status;
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* __TZ_get_PSPLIM_NS Intrinsic to get NS PSP */
@@ -179,18 +207,22 @@ UINT status;
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
-ULONG sp;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
@@ -200,23 +232,38 @@ ULONG sp;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -224,38 +271,41 @@ ULONG sp;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
- /* Check if this thread is running by looking at PSP_NS and seeing if it is within
- the stack_start and stack_end range. */
- sp = __TZ_get_PSP_NS();
- if(sp > ((ULONG) thread_ptr -> tx_thread_stack_start) && sp < ((ULONG) thread_ptr -> tx_thread_stack_end))
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
+ /* Check if this thread is running by looking at its stack start and PSPLIM_NS */
+ if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == __TZ_get_PSPLIM_NS())
{
/* If this thread is running, set Secure PSP and PSPLIM. */
__set_PSPLIM((ULONG)(info_ptr -> tx_thread_secure_stack_limit));
__set_PSP((ULONG)(info_ptr -> tx_thread_secure_stack_ptr));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -266,7 +316,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M23/AC6 */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -301,44 +351,65 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -349,7 +420,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M23/AC6 */
-/* 6.1.7 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -386,6 +457,9 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* resulting in version 6.1.1 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -393,38 +467,45 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
sp = __get_PSP();
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
return;
}
@@ -435,7 +516,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M23/AC6 */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -469,32 +550,42 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
__set_PSPLIM((ULONG)info_ptr -> tx_thread_secure_stack_limit);
__set_PSP ((ULONG)info_ptr -> tx_thread_secure_stack_ptr);
-
+
return;
}
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack_initialize.S b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
index c2f9bf31..bada32ce 100644
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
+++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_initialize Cortex-M23/AC6 */
-/* 6.1.8 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -49,13 +49,17 @@
/* */
/* CALLED BY */
/* */
-/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 08-02-2021 Scott Larson Initial Version 6.1.8 */
+/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_secure_stack_initialize(VOID)
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 8e3cff23..00000000
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M23 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m23/gnu/inc/tx_port.h b/ports_module/cortex_m23/gnu/inc/tx_port.h
index 42486b17..330d08e2 100644
--- a/ports_module/cortex_m23/gnu/inc/tx_port.h
+++ b/ports_module/cortex_m23/gnu/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -61,6 +61,10 @@
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -385,7 +389,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -484,7 +488,7 @@ unsigned int interrupt_save;
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1.11 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
index 7b640e6f..439a96c0 100644
--- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -61,6 +61,9 @@
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -375,15 +378,6 @@ _skip_secure_restore:
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c
index 8f22bb90..ac7c70a5 100644
--- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -44,8 +44,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -53,8 +59,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -62,7 +74,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M23/GNU */
-/* 6.1.8 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -94,10 +106,13 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Modified comment(s), changed */
+/* 06-02-2021 Scott Larson Modified comment(s), changed */
/* name, execute in handler */
/* mode, disable optimization, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry, optimize(0)))
@@ -106,6 +121,7 @@ UINT _tx_thread_secure_mode_stack_initialize(void)
UINT status;
ULONG control;
ULONG ipsr;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -119,12 +135,26 @@ ULONG ipsr;
asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */
control |= 2; /* Use PSP. */
asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
asm volatile("MSR PSPLIM, %0" :: "r" (0));
asm volatile("MSR PSP, %0" :: "r" (0));
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -137,7 +167,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M23/GNU */
-/* 6.1.3 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -160,9 +190,7 @@ ULONG ipsr;
/* */
/* CALLS */
/* */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* */
/* CALLED BY */
/* */
@@ -179,20 +207,26 @@ ULONG ipsr;
/* 12-31-2020 Scott Larson Modified comment(s), and */
/* fixed M23 GCC build, */
/* resulting in version 6.1.3 */
-
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
ULONG ipsr;
ULONG psplim_ns;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
if (ipsr == 0)
@@ -203,23 +237,38 @@ ULONG psplim_ns;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -227,13 +276,13 @@ ULONG psplim_ns;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
/* Check if this thread is running by looking at its stack start and PSPLIM_NS */
asm volatile("MRS %0, PSPLIM_NS" : "=r" (psplim_ns)); /* Get PSPLIM_NS register. */
if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == psplim_ns)
@@ -243,21 +292,26 @@ ULONG psplim_ns;
asm volatile("MSR PSP, %0" :: "r" ((ULONG)(info_ptr -> tx_thread_secure_stack_ptr)));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -268,7 +322,7 @@ ULONG psplim_ns;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M23/GNU */
-/* 6.1.3 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -305,46 +359,67 @@ ULONG psplim_ns;
/* 12-31-2020 Scott Larson Modified comment(s), and */
/* fixed M23 GCC build, */
/* resulting in version 6.1.3 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG ipsr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
if (ipsr == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -355,7 +430,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M23/GNU */
-/* 6.1.7 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -392,6 +467,9 @@ ULONG ipsr;
/* resulting in version 6.1.3 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -400,6 +478,7 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
ULONG ipsr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -407,32 +486,38 @@ ULONG ipsr;
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
asm volatile("MRS %0, PSP" : "=r" (sp)); /* Get PSP register. */
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
asm volatile("MSR PSPLIM, %0" :: "r" (0));
asm volatile("MSR PSP, %0" :: "r" (0));
-
+
return;
}
@@ -443,7 +528,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M23/GNU */
-/* 6.1.3 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -478,6 +563,9 @@ ULONG ipsr;
/* 12-31-2020 Scott Larson Modified comment(s), and */
/* fixed M23 GCC build, */
/* resulting in version 6.1.3 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -485,6 +573,7 @@ void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG ipsr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -492,20 +581,26 @@ ULONG ipsr;
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
asm volatile("MSR PSPLIM, %0" :: "r" ((ULONG)info_ptr -> tx_thread_secure_stack_limit));
asm volatile("MSR PSP, %0" :: "r" ((ULONG)info_ptr -> tx_thread_secure_stack_ptr));
-
+
return;
}
diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack_initialize.S
index 75ad1f32..7efcef40 100644
--- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_notify.c
+++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_secure_stack_initialize.S
@@ -20,77 +20,64 @@
/**************************************************************************/
/**************************************************************************/
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_stack_error_notify Cortex-M23 */
-/* 6.1 */
+/* _tx_thread_secure_stack_initialize Cortex-M23/GNU */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
+/* This function enters the SVC handler to initialize a secure stack. */
/* */
/* INPUT */
/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
+/* none */
/* */
/* OUTPUT */
/* */
-/* status Service return status */
+/* none */
/* */
/* CALLS */
/* */
-/* None */
+/* SVC 3 */
/* */
/* CALLED BY */
/* */
-/* Application Code */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
+// VOID _tx_thread_secure_stack_initialize(VOID)
+// {
+ .section .text
+ .balign 4
+ .syntax unified
+ .eabi_attribute Tag_ABI_align_preserved, 1
+ .global _tx_thread_secure_stack_initialize
+ .thumb_func
+.type _tx_thread_secure_stack_initialize, function
+_tx_thread_secure_stack_initialize:
+#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
+ CPSIE i // Enable interrupts for SVC call
+ SVC 3
+ CPSID i // Disable interrupts
+#else
+ MOV r0, #0xFF // Feature not enabled
+#endif
+ BX lr
+ .end
diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 8e3cff23..00000000
--- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M23 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_notify.c
deleted file mode 100644
index 75ad1f32..00000000
--- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_stack_error_notify.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_notify Cortex-M23 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
-/* */
-/* OUTPUT */
-/* */
-/* status Service return status */
-/* */
-/* CALLS */
-/* */
-/* None */
-/* */
-/* CALLED BY */
-/* */
-/* Application Code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
diff --git a/ports_module/cortex_m23/iar/inc/tx_port.h b/ports_module/cortex_m23/iar/inc/tx_port.h
index 418ffa05..36016ea5 100644
--- a/ports_module/cortex_m23/iar/inc/tx_port.h
+++ b/ports_module/cortex_m23/iar/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -51,6 +51,10 @@
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -589,7 +593,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -704,7 +708,7 @@ VOID _tx_thread_interrupt_restore(UIN
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/IAR Version 6.1.11 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/IAR Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
index 9e6d58bb..00f1189a 100644
--- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M23/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -77,6 +77,9 @@
/* 04-02-2021 Scott Larson Initial Version 6.1.6 */
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -376,15 +379,6 @@ _skip_secure_restore:
LDR r2, [r0, r2] // Pickup MPU data region address
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOVS r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
- LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
-
// Initialize loop to configure MPU registers
MOVS r3, #0x64 // Index of MPU register settings in thread control block
ADD r0, r0, r3 // Build address of MPU register start in thread control block
diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c
index 1bb31a36..7cb0061e 100644
--- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -45,8 +45,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -54,8 +60,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -63,7 +75,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M23/IAR */
-/* 6.1.8 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -98,16 +110,20 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Modified comment(s), changed */
+/* 06-02-2021 Scott Larson Modified comment(s), changed */
/* name, execute in handler */
/* mode, disable optimization, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_initialize(void)
{
UINT status;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
@@ -118,12 +134,26 @@ UINT status;
{
/* Set secure mode to use PSP. */
__set_CONTROL(__get_CONTROL() | 2);
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -136,7 +166,7 @@ UINT status;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M23/IAR */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -160,9 +190,7 @@ UINT status;
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* __TZ_get_PSPLIM_NS Intrinsic to get NS PSP */
@@ -179,18 +207,24 @@ UINT status;
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
-ULONG sp;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
@@ -200,23 +234,38 @@ ULONG sp;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -224,38 +273,41 @@ ULONG sp;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
- /* Check if this thread is running by looking at PSP_NS and seeing if it is within
- the stack_start and stack_end range. */
- sp = __TZ_get_PSP_NS();
- if(sp > ((ULONG) thread_ptr -> tx_thread_stack_start) && sp < ((ULONG) thread_ptr -> tx_thread_stack_end))
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
+ /* Check if this thread is running by looking at its stack start and PSPLIM_NS */
+ if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == __TZ_get_PSPLIM_NS())
{
/* If this thread is running, set Secure PSP and PSPLIM. */
__set_PSPLIM((ULONG)(info_ptr -> tx_thread_secure_stack_limit));
__set_PSP((ULONG)(info_ptr -> tx_thread_secure_stack_ptr));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -266,7 +318,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M23/IAR */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -301,44 +353,67 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -349,7 +424,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M23/IAR */
-/* 6.1.7 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -386,6 +461,9 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* resulting in version 6.1.1 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -393,38 +471,45 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
sp = __get_PSP();
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
return;
}
@@ -435,7 +520,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M23/IAR */
-/* 6.1.1 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -469,32 +554,42 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 07-29-2022 Scott Larson Modified comments, updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
__set_PSPLIM((ULONG)info_ptr -> tx_thread_secure_stack_limit);
__set_PSP ((ULONG)info_ptr -> tx_thread_secure_stack_ptr);
-
+
return;
}
diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack_initialize.s
index 75ad1f32..26ec4fb5 100644
--- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_stack_error_notify.c
+++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_secure_stack_initialize.s
@@ -20,77 +20,59 @@
/**************************************************************************/
/**************************************************************************/
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
+ SECTION `.text`:CODE:NOROOT(2)
+ THUMB
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_stack_error_notify Cortex-M23 */
-/* 6.1 */
+/* _tx_thread_secure_stack_initialize Cortex-M23/IAR */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
+/* This function enters the SVC handler to initialize a secure stack. */
/* */
/* INPUT */
/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
+/* none */
/* */
/* OUTPUT */
/* */
-/* status Service return status */
+/* none */
/* */
/* CALLS */
/* */
-/* None */
+/* SVC 3 */
/* */
/* CALLED BY */
/* */
-/* Application Code */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
+// VOID _tx_thread_secure_stack_initialize(VOID)
+// {
+ EXPORT _tx_thread_secure_stack_initialize
+_tx_thread_secure_stack_initialize:
+#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
+ CPSIE i // Enable interrupts for SVC call
+ SVC 3
+ CPSID i // Disable interrupts
+#else
+ MOV r0, #0xFF // Feature not enabled
+#endif
+ BX lr
+ END
diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 8e3cff23..00000000
--- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M23 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m3/ac5/inc/txm_module_port.h b/ports_module/cortex_m3/ac5/inc/txm_module_port.h
index d3bcdee8..523c787a 100644
--- a/ports_module/cortex_m3/ac5/inc/txm_module_port.h
+++ b/ports_module/cortex_m3/ac5/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M3/AC5 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
diff --git a/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s
index 6f0f91df..11838470 100644
--- a/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC5 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -76,6 +76,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +389,33 @@ __tx_ts_restore
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,6 +423,7 @@ __tx_ts_restore
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
@@ -420,6 +432,7 @@ _tx_enable_mpu
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __TARGET_FPU_VFP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -573,14 +586,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
index 48a14571..4a00404f 100644
--- a/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m3/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M3 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m3/ac6/inc/txm_module_port.h b/ports_module/cortex_m3/ac6/inc/txm_module_port.h
index 75621757..235aca2c 100644
--- a/ports_module/cortex_m3/ac6/inc/txm_module_port.h
+++ b/ports_module/cortex_m3/ac6/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M3/AC6 */
-/* 6.1.10 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 01-31-2022 Scott Larson Modified comments and made */
/* heap user-configurable, */
/* resulting in version 6.1.10 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -119,6 +122,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -384,6 +441,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/AC6 Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/AC6 Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m3/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m3/ac6/module_lib/src/txm_module_thread_shell_entry.c
index efe4d9b0..750afe31 100644
--- a/ports_module/cortex_m3/ac6/module_lib/src/txm_module_thread_shell_entry.c
+++ b/ports_module/cortex_m3/ac6/module_lib/src/txm_module_thread_shell_entry.c
@@ -57,7 +57,7 @@ extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-M3/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
index 4cf1df38..00ab9053 100644
--- a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
diff --git a/ports_module/cortex_m3/ac6/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m3/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
index 48a14571..4a00404f 100644
--- a/ports_module/cortex_m3/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m3/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M3 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m3/gnu/example_build/build_threadx_sample.bat b/ports_module/cortex_m3/gnu/example_build/build_threadx_sample.bat
new file mode 100644
index 00000000..af3156de
--- /dev/null
+++ b/ports_module/cortex_m3/gnu/example_build/build_threadx_sample.bat
@@ -0,0 +1,4 @@
+arm-none-eabi-gcc -c -g -mcpu=cortex-m3 -mthumb -I..\inc -I..\..\..\..\common\inc sample_threadx.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m3 -mthumb tx_simulator_startup.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m3 -mthumb cortexm_crt0.S
+arm-none-eabi-ld -A cortex-m3 -ereset_handler -T sample_threadx.ld tx_simulator_startup.o cortexm_crt0.o sample_threadx.o tx.a libc.a -o sample_threadx.axf -M > sample_threadx.map
diff --git a/ports_module/cortex_m3/gnu/inc/txm_module_port.h b/ports_module/cortex_m3/gnu/inc/txm_module_port.h
index 58ed9614..c77eb2f0 100644
--- a/ports_module/cortex_m3/gnu/inc/txm_module_port.h
+++ b/ports_module/cortex_m3/gnu/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M3/GNU */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -376,6 +433,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/GNU Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/GNU Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
index e5d101b5..a8b3894f 100644
--- a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -588,14 +602,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m3/gnu/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m3/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
index 48a14571..4a00404f 100644
--- a/ports_module/cortex_m3/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m3/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M3 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m3/iar/inc/txm_module_port.h b/ports_module/cortex_m3/iar/inc/txm_module_port.h
index d3f38fec..5c8aa17e 100644
--- a/ports_module/cortex_m3/iar/inc/txm_module_port.h
+++ b/ports_module/cortex_m3/iar/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M3/IAR */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -112,6 +115,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -377,6 +434,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/IAR Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M3/IAR Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
index 6326b800..b83ec527 100644
--- a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s
@@ -28,6 +28,7 @@
EXTERN _tx_thread_preempt_disable
EXTERN _txm_module_manager_memory_fault_handler
EXTERN _txm_module_manager_memory_fault_info
+ EXTERN txm_module_default_mpu_registers
SECTION `.text`:CODE:NOROOT(2)
THUMB
@@ -36,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M3/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -72,6 +73,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +390,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,14 +424,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARMVFP__
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -574,14 +589,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m3/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m3/iar/module_manager/src/txm_module_manager_mm_register_setup.c
index 48a14571..4a00404f 100644
--- a/ports_module/cortex_m3/iar/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m3/iar/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M3 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m33/ac6/inc/tx_port.h b/ports_module/cortex_m33/ac6/inc/tx_port.h
index e3547602..0b44956c 100644
--- a/ports_module/cortex_m33/ac6/inc/tx_port.h
+++ b/ports_module/cortex_m33/ac6/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -64,13 +64,18 @@
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
-/* 01-31-2022 Scott Larson Modified comment(s), unified */
+/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* described BASEPRI usage, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -188,6 +193,12 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
/* Define various constants for the ThreadX Cortex-M port. */
@@ -582,7 +593,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -695,7 +706,7 @@ VOID _tx_thread_interrupt_restore(UIN
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m33/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m33/ac6/module_lib/src/txm_module_thread_shell_entry.c
index ad2c6205..da78d6ae 100644
--- a/ports_module/cortex_m33/ac6/module_lib/src/txm_module_thread_shell_entry.c
+++ b/ports_module/cortex_m33/ac6/module_lib/src/txm_module_thread_shell_entry.c
@@ -58,7 +58,7 @@ extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-M33/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
index c196f75a..417d1404 100644
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S
@@ -30,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -72,6 +72,9 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -424,14 +427,7 @@ _skip_secure_restore:
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOV r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack.c
index 5089f39b..099ae737 100644
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -45,8 +45,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -54,8 +60,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -63,7 +75,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M33/AC6 */
-/* 6.1.8 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -98,16 +110,20 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Modified comment(s), and */
+/* 06-02-2021 Scott Larson Modified comment(s), and */
/* changed name, execute in */
/* handler mode, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_initialize(void)
{
UINT status;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
@@ -118,12 +134,26 @@ UINT status;
{
/* Set secure mode to use PSP. */
__set_CONTROL(__get_CONTROL() | 2);
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -136,7 +166,7 @@ UINT status;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M33/AC6 */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -160,9 +190,7 @@ UINT status;
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* __TZ_get_PSPLIM_NS Intrinsic to get NS PSP */
@@ -179,17 +207,22 @@ UINT status;
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
@@ -199,23 +232,38 @@ UCHAR *stack_mem;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -223,13 +271,13 @@ UCHAR *stack_mem;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
/* Check if this thread is running by looking at its stack start and PSPLIM_NS */
if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == __TZ_get_PSPLIM_NS())
{
@@ -238,21 +286,26 @@ UCHAR *stack_mem;
__set_PSP((ULONG)(info_ptr -> tx_thread_secure_stack_ptr));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -263,7 +316,7 @@ UCHAR *stack_mem;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M33/AC6 */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -298,44 +351,65 @@ UCHAR *stack_mem;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -346,7 +420,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M33/AC6 */
-/* 6.1.7 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -383,6 +457,9 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* resulting in version 6.1.1 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -390,38 +467,45 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
sp = __get_PSP();
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
return;
}
@@ -432,7 +516,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M33/AC6 */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -466,32 +550,42 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
__set_PSPLIM((ULONG)info_ptr -> tx_thread_secure_stack_limit);
__set_PSP ((ULONG)info_ptr -> tx_thread_secure_stack_ptr);
-
+
return;
}
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack_initialize.S b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
index e7cd43e8..a96e30ab 100644
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
+++ b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_secure_stack_initialize.S
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_initialize Cortex-M33/AC6 */
-/* 6.1.8 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -49,13 +49,17 @@
/* */
/* CALLED BY */
/* */
-/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 08-02-2021 Scott Larson Initial Version 6.1.8 */
+/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_secure_stack_initialize(VOID)
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 4d3bbee7..00000000
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M33 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m33/gnu/inc/tx_port.h b/ports_module/cortex_m33/gnu/inc/tx_port.h
index e3547602..0b44956c 100644
--- a/ports_module/cortex_m33/gnu/inc/tx_port.h
+++ b/ports_module/cortex_m33/gnu/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -64,13 +64,18 @@
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
-/* 01-31-2022 Scott Larson Modified comment(s), unified */
+/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* described BASEPRI usage, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -188,6 +193,12 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
/* Define various constants for the ThreadX Cortex-M port. */
@@ -582,7 +593,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -695,7 +706,7 @@ VOID _tx_thread_interrupt_restore(UIN
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
index ff454e9c..af8be2ba 100644
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S
@@ -29,7 +29,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -73,6 +73,9 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -425,14 +428,7 @@ _skip_secure_restore:
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOV r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack.c
index 9375062c..13bfc29a 100644
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -44,8 +44,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -53,8 +59,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -62,7 +74,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M33/GNU */
-/* 6.1.8 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -94,10 +106,13 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Change name, execute in */
+/* 06-02-2021 Scott Larson Change name, execute in */
/* handler mode, */
/* disable optimizations, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry, optimize(0)))
@@ -106,6 +121,7 @@ UINT _tx_thread_secure_mode_stack_initialize(void)
UINT status;
ULONG control;
ULONG ipsr;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -119,12 +135,26 @@ ULONG ipsr;
asm volatile("MRS %0, CONTROL" : "=r" (control)); /* Get CONTROL register. */
control |= 2; /* Use PSP. */
asm volatile("MSR CONTROL, %0" :: "r" (control)); /* Set CONTROL register. */
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
asm volatile("MSR PSPLIM, %0" :: "r" (0));
asm volatile("MSR PSP, %0" :: "r" (0));
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -137,7 +167,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M33/GNU */
-/* 6.1.1 */
+/* 6.1.11a */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -160,9 +190,7 @@ ULONG ipsr;
/* */
/* CALLS */
/* */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* */
/* CALLED BY */
/* */
@@ -176,19 +204,27 @@ ULONG ipsr;
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
+/* 05-02-2022 Scott Larson Modified comment(s), added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.11a*/
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
ULONG ipsr;
ULONG psplim_ns;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
if (ipsr == 0)
@@ -199,23 +235,38 @@ ULONG psplim_ns;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -223,13 +274,13 @@ ULONG psplim_ns;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
/* Check if this thread is running by looking at its stack start and PSPLIM_NS */
asm volatile("MRS %0, PSPLIM_NS" : "=r" (psplim_ns)); /* Get PSPLIM_NS register. */
if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == psplim_ns)
@@ -239,21 +290,26 @@ ULONG psplim_ns;
asm volatile("MSR PSP, %0" :: "r" ((ULONG)(info_ptr -> tx_thread_secure_stack_ptr)));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -264,7 +320,7 @@ ULONG psplim_ns;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M33/GNU */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -298,46 +354,67 @@ ULONG psplim_ns;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG ipsr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
if (ipsr == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -348,7 +425,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M33/GNU */
-/* 6.1.7 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -382,6 +459,9 @@ ULONG ipsr;
/* resulting in version 6.1.1 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -390,6 +470,7 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
ULONG ipsr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -397,32 +478,38 @@ ULONG ipsr;
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
asm volatile("MRS %0, PSP" : "=r" (sp)); /* Get PSP register. */
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
asm volatile("MSR PSPLIM, %0" :: "r" (0));
asm volatile("MSR PSP, %0" :: "r" (0));
-
+
return;
}
@@ -433,7 +520,7 @@ ULONG ipsr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M33/GNU */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -465,6 +552,9 @@ ULONG ipsr;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -472,6 +562,7 @@ void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG ipsr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
@@ -479,20 +570,26 @@ ULONG ipsr;
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
asm volatile("MSR PSPLIM, %0" :: "r" ((ULONG)info_ptr -> tx_thread_secure_stack_limit));
asm volatile("MSR PSP, %0" :: "r" ((ULONG)info_ptr -> tx_thread_secure_stack_ptr));
-
+
return;
}
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack_initialize.S b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack_initialize.S
index 9e9642fc..a9f899f6 100644
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack_initialize.S
+++ b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_secure_stack_initialize.S
@@ -26,7 +26,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_initialize Cortex-M33/GNU */
-/* 6.1.7 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -49,13 +49,17 @@
/* */
/* CALLED BY */
/* */
-/* TX_INITIALIZE_KERNEL_ENTER_EXTENSION */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_secure_stack_initialize(VOID)
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 4d3bbee7..00000000
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M33 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_notify.c
deleted file mode 100644
index d61a27b3..00000000
--- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_stack_error_notify.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_notify Cortex-M33 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
-/* */
-/* OUTPUT */
-/* */
-/* status Service return status */
-/* */
-/* CALLS */
-/* */
-/* None */
-/* */
-/* CALLED BY */
-/* */
-/* Application Code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
diff --git a/ports_module/cortex_m33/iar/inc/tx_port.h b/ports_module/cortex_m33/iar/inc/tx_port.h
index e3547602..0b44956c 100644
--- a/ports_module/cortex_m33/iar/inc/tx_port.h
+++ b/ports_module/cortex_m33/iar/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M33 */
-/* 6.1.11 */
+/* 6.1.12 */
/* */
/* AUTHOR */
/* */
@@ -64,13 +64,18 @@
/* 10-15-2021 Scott Larson Modified comment(s), improved */
/* stack check error handling, */
/* resulting in version 6.1.9 */
-/* 01-31-2022 Scott Larson Modified comment(s), unified */
+/* 01-31-2022 Scott Larson Modified comment(s), unified */
/* this file across compilers, */
/* fixed predefined macro, */
/* resulting in version 6.1.10 */
/* 04-25-2022 Scott Larson Modified comments and added */
/* volatile to registers, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* described BASEPRI usage, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -188,6 +193,12 @@ UINT _tx_thread_secure_stack_free(struct TX_THREAD_STRUCT *tx_thread);
#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
#endif
+/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts.
+If using BASEPRI is desired, define the following two symbols for both c and assembly files:
+TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK.
+TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask.
+Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run.
+*/
/* Define various constants for the ThreadX Cortex-M port. */
@@ -582,7 +593,7 @@ ULONG _tx_misra_ipsr_get(VOID);
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
/* Initialize secure stacks for threads calling secure functions. */
extern void _tx_thread_secure_stack_initialize(void);
-#define TX_INITIALIZE_KERNEL_ENTER_EXTENSION _tx_thread_secure_stack_initialize();
+#define TX_PORT_SPECIFIC_PRE_INITIALIZATION _tx_thread_secure_stack_initialize();
#endif
/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to
@@ -695,7 +706,7 @@ VOID _tx_thread_interrupt_restore(UIN
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M33 Version 6.1.12 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
index e4d4bfd3..3242fac2 100644
--- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M33/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -84,6 +84,9 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -421,14 +424,7 @@ _skip_secure_restore:
LDR r2, [r0, #0x74] // Pickup MPU address of data region
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
- // Is the MPU already set up for this module?
- MOV r1, #2 // Select MPU region 2
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 2
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 2
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
LDR r2, =0xE000ED98 // Get region register
diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack.c b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack.c
index 64006f59..83e6c37d 100644
--- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack.c
+++ b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack.c
@@ -23,7 +23,7 @@
#include "tx_api.h"
-/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
+/* If TX_SINGLE_MODE_SECURE or TX_SINGLE_MODE_NON_SECURE is defined,
no secure stack functionality is needed. */
#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
@@ -45,8 +45,14 @@
#define TX_THREAD_STACK_SEAL_SIZE 8
#define TX_THREAD_STACK_SEAL_VALUE 0xFEF5EDA5
-/* Secure stack info struct to hold stack start, stack limit,
- current stack pointer, and pointer to owning thread.
+/* max number of Secure context */
+#ifndef TX_MAX_SECURE_CONTEXTS
+#define TX_MAX_SECURE_CONTEXTS 32
+#endif
+#define TX_INVALID_SECURE_CONTEXT_IDX (-1)
+
+/* Secure stack info struct to hold stack start, stack limit,
+ current stack pointer, and pointer to owning thread.
This will be allocated for each thread with a secure stack. */
typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
{
@@ -54,8 +60,14 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
VOID *tx_thread_secure_stack_start; /* Thread's secure stack start address */
VOID *tx_thread_secure_stack_limit; /* Thread's secure stack limit */
TX_THREAD *tx_thread_ptr; /* Keep track of thread for error handling */
+ INT tx_next_free_index; /* Next free index of free secure context */
} TX_THREAD_SECURE_STACK_INFO;
+/* Static secure contexts */
+static TX_THREAD_SECURE_STACK_INFO tx_thread_secure_context[TX_MAX_SECURE_CONTEXTS];
+/* Head of free secure context */
+static INT tx_head_free_index = 0U;
+
/**************************************************************************/
@@ -63,7 +75,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_initialize Cortex-M33/IAR */
-/* 6.1.8 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -98,15 +110,19 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
-/* 08-02-2021 Scott Larson Change name, execute in */
+/* 06-02-2021 Scott Larson Change name, execute in */
/* handler mode, */
-/* resulting in version 6.1.8 */
+/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_initialize(void)
{
UINT status;
+INT index;
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
@@ -117,12 +133,26 @@ UINT status;
{
/* Set secure mode to use PSP. */
__set_CONTROL(__get_CONTROL() | 2);
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
+ for (index = 0; index < TX_MAX_SECURE_CONTEXTS; index++)
+ {
+
+ /* Check last index and mark next free to invalid index */
+ if(index == (TX_MAX_SECURE_CONTEXTS - 1))
+ {
+ tx_thread_secure_context[index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ tx_thread_secure_context[index].tx_next_free_index = index + 1;
+ }
+ }
+
status = TX_SUCCESS;
}
return status;
@@ -135,7 +165,7 @@ UINT status;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M33/IAR */
-/* 6.1.1 */
+/* 6.1.11a */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -159,9 +189,7 @@ UINT status;
/* CALLS */
/* */
/* __get_IPSR Intrinsic to get IPSR */
-/* calloc Compiler's calloc function */
/* malloc Compiler's malloc function */
-/* free Compiler's free() function */
/* __set_PSPLIM Intrinsic to set PSP limit */
/* __set_PSP Intrinsic to set PSP */
/* __TZ_get_PSPLIM_NS Intrinsic to get NS PSP */
@@ -178,17 +206,25 @@ UINT status;
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
+/* 05-02-2022 Scott Larson Modified comment(s), added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.11a*/
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack_size)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
+INT secure_context_index;
status = TX_SUCCESS;
-
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
@@ -198,23 +234,38 @@ UCHAR *stack_mem;
{
status = TX_SIZE_ERROR;
}
-
+
/* Check if thread already has secure stack allocated. */
else if (thread_ptr -> tx_thread_secure_stack_context != 0)
{
status = TX_THREAD_ERROR;
}
-
+
else
{
- /* Allocate space for secure stack info. */
- info_ptr = calloc(1, sizeof(TX_THREAD_SECURE_STACK_INFO));
-
- if(info_ptr != TX_NULL)
+ TX_DISABLE
+
+ /* Allocate free index for secure stack info. */
+ if(tx_head_free_index != TX_INVALID_SECURE_CONTEXT_IDX)
+ {
+ secure_context_index = tx_head_free_index;
+ tx_head_free_index = tx_thread_secure_context[tx_head_free_index].tx_next_free_index;
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+ else
+ {
+ secure_context_index = TX_INVALID_SECURE_CONTEXT_IDX;
+ }
+
+ TX_RESTORE
+
+ if(secure_context_index != TX_INVALID_SECURE_CONTEXT_IDX)
{
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* If stack info allocated, allocate a stack & seal. */
stack_mem = malloc(stack_size + TX_THREAD_STACK_SEAL_SIZE);
-
+
if(stack_mem != TX_NULL)
{
/* Secure stack has been allocated, save in the stack info struct. */
@@ -222,13 +273,13 @@ UCHAR *stack_mem;
info_ptr -> tx_thread_secure_stack_start = stack_mem + stack_size;
info_ptr -> tx_thread_secure_stack_ptr = info_ptr -> tx_thread_secure_stack_start;
info_ptr -> tx_thread_ptr = thread_ptr;
-
+
/* Seal bottom of stack. */
*(ULONG*)info_ptr -> tx_thread_secure_stack_start = TX_THREAD_STACK_SEAL_VALUE;
-
- /* Save info pointer in thread. */
- thread_ptr -> tx_thread_secure_stack_context = info_ptr;
-
+
+ /* Save secure context id (i.e non-zero base index) in thread. */
+ thread_ptr -> tx_thread_secure_stack_context = (VOID *)(secure_context_index + 1);
+
/* Check if this thread is running by looking at its stack start and PSPLIM_NS */
if(((ULONG) thread_ptr -> tx_thread_stack_start & 0xFFFFFFF8) == __TZ_get_PSPLIM_NS())
{
@@ -237,21 +288,26 @@ UCHAR *stack_mem;
__set_PSP((ULONG)(info_ptr -> tx_thread_secure_stack_ptr));
}
}
-
+
else
{
+ TX_DISABLE
+
/* Stack not allocated, free the info struct. */
- free(info_ptr);
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
status = TX_NO_MEMORY;
}
}
-
+
else
{
status = TX_NO_MEMORY;
}
}
-
+
return(status);
}
@@ -262,7 +318,7 @@ UCHAR *stack_mem;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M33/IAR */
-/* 6.1.1 */
+/* 6.1.11a */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -297,44 +353,68 @@ UCHAR *stack_mem;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
+/* 05-02-2022 Scott Larson Modified comment(s), added */
+/* TX_INTERRUPT_SAVE_AREA, */
+/* resulting in version 6.1.11a*/
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
+TX_INTERRUPT_SAVE_AREA
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index;
status = TX_SUCCESS;
-
- /* Pickup stack info from thread. */
- info_ptr = thread_ptr -> tx_thread_secure_stack_context;
-
+
+ /* Pickup stack info id from thread. */
+ secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
+
/* Make sure function is called from interrupt (threads should not call). */
if (__get_IPSR() == 0)
{
status = TX_CALLER_ERROR;
}
-
- /* Check that this secure context is for this thread. */
- else if (info_ptr -> tx_thread_ptr != thread_ptr)
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
{
status = TX_THREAD_ERROR;
}
-
else
{
-
- /* Free secure stack. */
- free(info_ptr -> tx_thread_secure_stack_limit);
-
- /* Free info struct. */
- free(info_ptr);
-
- /* Clear secure context from thread. */
- thread_ptr -> tx_thread_secure_stack_context = 0;
+
+ /* Pickup stack info from static array of secure contexts. */
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
+ /* Check that this secure context is for this thread. */
+ if (info_ptr -> tx_thread_ptr != thread_ptr)
+ {
+ status = TX_THREAD_ERROR;
+ }
+
+ else
+ {
+
+ /* Free secure stack. */
+ free(info_ptr -> tx_thread_secure_stack_limit);
+
+ TX_DISABLE
+
+ /* Free info struct. */
+ tx_thread_secure_context[secure_context_index].tx_next_free_index = tx_head_free_index;
+ tx_head_free_index = secure_context_index;
+ TX_RESTORE
+
+ /* Clear secure context from thread. */
+ thread_ptr -> tx_thread_secure_stack_context = 0;
+ }
}
-
+
return(status);
}
@@ -345,7 +425,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M33/IAR */
-/* 6.1.7 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -382,6 +462,9 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* resulting in version 6.1.1 */
/* 06-02-2021 Scott Larson Fix stack pointer save, */
/* resulting in version 6.1.7 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -389,38 +472,45 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Check that stack pointer is in range */
sp = __get_PSP();
- if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
+ if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
return;
}
-
+
/* Save stack pointer. */
info_ptr -> tx_thread_secure_stack_ptr = (VOID *) sp;
-
+
/* Set process stack pointer and stack limit to 0 to throw exception when a thread
without a secure stack calls a secure function that tries to use secure stack. */
__set_PSPLIM(0);
__set_PSP(0);
-
+
return;
}
@@ -431,7 +521,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M33/IAR */
-/* 6.1.1 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -465,32 +555,42 @@ ULONG sp;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 01-31-2022 Himanshu Gupta Modified comments(s), updated */
+/* secure stack allocation, */
+/* resulting in version 6.1.10 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+INT secure_context_index = (INT)thread_ptr -> tx_thread_secure_stack_context - 1;
/* This function should be called from scheduler only. */
if (__get_IPSR() == 0)
{
return;
}
-
+
+ /* Check if secure context index is in valid range. */
+ else if (secure_context_index < 0 || secure_context_index >= TX_MAX_SECURE_CONTEXTS)
+ {
+ return;
+ }
+
/* Pickup the secure context pointer. */
- info_ptr = (TX_THREAD_SECURE_STACK_INFO *)(thread_ptr -> tx_thread_secure_stack_context);
-
+ info_ptr = &tx_thread_secure_context[secure_context_index];
+
/* Check that this secure context is for this thread. */
if (info_ptr -> tx_thread_ptr != thread_ptr)
{
return;
}
-
+
/* Set stack pointer and limit. */
__set_PSPLIM((ULONG)info_ptr -> tx_thread_secure_stack_limit);
__set_PSP ((ULONG)info_ptr -> tx_thread_secure_stack_ptr);
-
+
return;
}
diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack_initialize.s
index d61a27b3..4fb1bb3c 100644
--- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_stack_error_notify.c
+++ b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_secure_stack_initialize.s
@@ -20,77 +20,59 @@
/**************************************************************************/
/**************************************************************************/
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
+ SECTION `.text`:CODE:NOROOT(2)
+ THUMB
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_stack_error_notify Cortex-M33 */
-/* 6.1 */
+/* _tx_thread_secure_stack_initialize Cortex-M33/IAR */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
+/* This function enters the SVC handler to initialize a secure stack. */
/* */
/* INPUT */
/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
+/* none */
/* */
/* OUTPUT */
/* */
-/* status Service return status */
+/* none */
/* */
/* CALLS */
/* */
-/* None */
+/* SVC 3 */
/* */
/* CALLED BY */
/* */
-/* Application Code */
+/* TX_PORT_SPECIFIC_PRE_INITIALIZATION */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 06-02-2021 Scott Larson Initial Version 6.1.7 */
+/* 07-29-2022 Scott Larson Modified comments and changed */
+/* secure stack initialization */
+/* macro to port-specific, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
+// VOID _tx_thread_secure_stack_initialize(VOID)
+// {
+ EXPORT _tx_thread_secure_stack_initialize
+_tx_thread_secure_stack_initialize:
+#if !defined(TX_SINGLE_MODE_SECURE) && !defined(TX_SINGLE_MODE_NON_SECURE)
+ CPSIE i // Enable interrupts for SVC call
+ SVC 3
+ CPSID i // Disable interrupts
+#else
+ MOV r0, #0xFF // Feature not enabled
+#endif
+ BX lr
+ END
diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_handler.c b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_handler.c
deleted file mode 100644
index 4d3bbee7..00000000
--- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_handler.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-
-/* Define the global function pointer for stack error handling. If a stack error is
- detected and the application has registered a stack error handler, it will be
- called via this function pointer. */
-
-VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_handler Cortex-M33 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function processes stack errors detected during run-time. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* */
-/* OUTPUT */
-/* */
-/* None */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_terminate */
-/* _tx_thread_application_stack_error_handler */
-/* */
-/* CALLED BY */
-/* */
-/* ThreadX internal code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-VOID _tx_thread_stack_error_handler(TX_THREAD *thread_ptr)
-{
- #ifndef TX_THREAD_NO_TERMINATE_STACK_ERROR
- /* Is there a thread? */
- if (thread_ptr)
- {
- /* Terminate the current thread. */
- _tx_thread_terminate(_tx_thread_current_ptr);
- }
- #endif
-
- /* Determine if the application has registered an error handler. */
- if (_tx_thread_application_stack_error_handler != TX_NULL)
- {
- /* Yes, an error handler is present, simply call the application error handler. */
- (_tx_thread_application_stack_error_handler)(thread_ptr);
- }
-}
diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_notify.c b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_notify.c
deleted file mode 100644
index d61a27b3..00000000
--- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_stack_error_notify.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************/
-/* */
-/* Copyright (c) Microsoft Corporation. All rights reserved. */
-/* */
-/* This software is licensed under the Microsoft Software License */
-/* Terms for Microsoft Azure RTOS. Full text of the license can be */
-/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
-/* and in the root directory of this software. */
-/* */
-/**************************************************************************/
-
-
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Thread */
-/** */
-/**************************************************************************/
-/**************************************************************************/
-
-#define TX_SOURCE_CODE
-
-
-/* Include necessary system files. */
-
-#include "tx_api.h"
-#include "tx_thread.h"
-#include "tx_trace.h"
-
-extern VOID (*_tx_thread_application_stack_error_handler)(TX_THREAD *thread_ptr);
-
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_stack_error_notify Cortex-M33 */
-/* 6.1 */
-/* AUTHOR */
-/* */
-/* Scott Larson, Microsoft Corporation */
-/* */
-/* DESCRIPTION */
-/* */
-/* This function registers an application stack error handler. If */
-/* ThreadX detects a stack error, this application handler is called. */
-/* */
-/* */
-/* INPUT */
-/* */
-/* stack_error_handler Pointer to stack error */
-/* handler, TX_NULL to disable */
-/* */
-/* OUTPUT */
-/* */
-/* status Service return status */
-/* */
-/* CALLS */
-/* */
-/* None */
-/* */
-/* CALLED BY */
-/* */
-/* Application Code */
-/* */
-/* RELEASE HISTORY */
-/* */
-/* DATE NAME DESCRIPTION */
-/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
-/* */
-/**************************************************************************/
-UINT _tx_thread_stack_error_notify(VOID (*stack_error_handler)(TX_THREAD *thread_ptr))
-{
-
-TX_INTERRUPT_SAVE_AREA
-
- /* Disable interrupts. */
- TX_DISABLE
-
- /* Make entry in event log. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_STACK_ERROR_NOTIFY, 0, 0, 0, 0, TX_TRACE_THREAD_EVENTS)
-
- /* Make entry in event log. */
- TX_EL_THREAD_STACK_ERROR_NOTIFY_INSERT
-
- /* Setup global thread stack error handler. */
- _tx_thread_application_stack_error_handler = stack_error_handler;
-
- /* Restore interrupts. */
- TX_RESTORE
-
- /* Return success to caller. */
- return(TX_SUCCESS);
-}
diff --git a/ports_module/cortex_m4/ac5/inc/txm_module_port.h b/ports_module/cortex_m4/ac5/inc/txm_module_port.h
index d4eeb650..f375107e 100644
--- a/ports_module/cortex_m4/ac5/inc/txm_module_port.h
+++ b/ports_module/cortex_m4/ac5/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M4/AC5 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
diff --git a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
index 11943fcf..6067dd44 100644
--- a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC5 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -76,6 +76,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +389,33 @@ __tx_ts_restore
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,6 +423,7 @@ __tx_ts_restore
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
@@ -420,6 +432,7 @@ _tx_enable_mpu
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __TARGET_FPU_VFP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -573,14 +586,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m4/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m4/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
index dcc8d2aa..36127034 100644
--- a/ports_module/cortex_m4/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m4/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M4 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m4/ac6/inc/txm_module_port.h b/ports_module/cortex_m4/ac6/inc/txm_module_port.h
index 5542fe83..27488cda 100644
--- a/ports_module/cortex_m4/ac6/inc/txm_module_port.h
+++ b/ports_module/cortex_m4/ac6/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M4/AC6 */
-/* 6.1.10 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 01-31-2022 Scott Larson Modified comments and made */
/* heap user-configurable, */
/* resulting in version 6.1.10 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -119,6 +122,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -384,6 +441,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/AC6 Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/AC6 Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m4/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m4/ac6/module_lib/src/txm_module_thread_shell_entry.c
index 5359f19b..82b33384 100644
--- a/ports_module/cortex_m4/ac6/module_lib/src/txm_module_thread_shell_entry.c
+++ b/ports_module/cortex_m4/ac6/module_lib/src/txm_module_thread_shell_entry.c
@@ -57,7 +57,7 @@ extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-M4/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
index d56fa398..cb50426c 100644
--- a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
diff --git a/ports_module/cortex_m4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
index dcc8d2aa..36127034 100644
--- a/ports_module/cortex_m4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m4/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M4 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m4/gnu/example_build/build_threadx_sample.bat b/ports_module/cortex_m4/gnu/example_build/build_threadx_sample.bat
new file mode 100644
index 00000000..21b6671c
--- /dev/null
+++ b/ports_module/cortex_m4/gnu/example_build/build_threadx_sample.bat
@@ -0,0 +1,5 @@
+arm-none-eabi-gcc -c -g -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfpv4 -mthumb cortexm_vectors.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfpv4 -mthumb cortexm_crt0.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfpv4 -mthumb tx_initialize_low_level.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfpv4 -mthumb -I..\inc -I..\..\..\..\common\inc sample_threadx.c
+arm-none-eabi-gcc -g -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=vfpv4 -mthumb -T sample_threadx.ld -ereset_handler -nostartfiles -o sample_threadx.out -Wl,-Map=sample_threadx.map cortexm_vectors.o cortexm_crt0.o tx_initialize_low_level.o sample_threadx.o tx.a
diff --git a/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S b/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S
new file mode 100644
index 00000000..d4cb1636
--- /dev/null
+++ b/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S
@@ -0,0 +1,127 @@
+ .global _start
+ .extern main
+
+
+ .section .init, "ax"
+ .code 16
+ .align 2
+ .thumb_func
+
+
+_start:
+ CPSID i
+ ldr r1, =__stack_end__
+ mov sp, r1
+
+
+ /* Copy initialised sections into RAM if required. */
+ ldr r0, =__data_load_start__
+ ldr r1, =__data_start__
+ ldr r2, =__data_end__
+ bl crt0_memory_copy
+ ldr r0, =__text_load_start__
+ ldr r1, =__text_start__
+ ldr r2, =__text_end__
+ bl crt0_memory_copy
+ ldr r0, =__fast_load_start__
+ ldr r1, =__fast_start__
+ ldr r2, =__fast_end__
+ bl crt0_memory_copy
+ ldr r0, =__ctors_load_start__
+ ldr r1, =__ctors_start__
+ ldr r2, =__ctors_end__
+ bl crt0_memory_copy
+ ldr r0, =__dtors_load_start__
+ ldr r1, =__dtors_start__
+ ldr r2, =__dtors_end__
+ bl crt0_memory_copy
+ ldr r0, =__rodata_load_start__
+ ldr r1, =__rodata_start__
+ ldr r2, =__rodata_end__
+ bl crt0_memory_copy
+
+
+ /* Zero bss. */
+ ldr r0, =__bss_start__
+ ldr r1, =__bss_end__
+ mov r2, #0
+ bl crt0_memory_set
+
+
+ /* Setup heap - not recommended for Threadx but here for compatibility reasons */
+ ldr r0, = __heap_start__
+ ldr r1, = __heap_end__
+ sub r1, r1, r0
+ mov r2, #0
+ str r2, [r0]
+ add r0, r0, #4
+ str r1, [r0]
+
+
+ /* constructors in case of using C++ */
+ ldr r0, =__ctors_start__
+ ldr r1, =__ctors_end__
+crt0_ctor_loop:
+ cmp r0, r1
+ beq crt0_ctor_end
+ ldr r2, [r0]
+ add r0, #4
+ push {r0-r1}
+ blx r2
+ pop {r0-r1}
+ b crt0_ctor_loop
+crt0_ctor_end:
+
+
+ /* Setup call frame for main() */
+ mov r0, #0
+ mov lr, r0
+ mov r12, sp
+
+
+start:
+ /* Jump to main() */
+ mov r0, #0
+ mov r1, #0
+ ldr r2, =main
+ blx r2
+ /* when main returns, loop forever. */
+crt0_exit_loop:
+ b crt0_exit_loop
+
+
+
+ /* Startup helper functions. */
+
+
+crt0_memory_copy:
+ cmp r0, r1
+ beq memory_copy_done
+ sub r2, r2, r1
+ beq memory_copy_done
+memory_copy_loop:
+ ldrb r3, [r0]
+ add r0, r0, #1
+ strb r3, [r1]
+ add r1, r1, #1
+ sub r2, r2, #1
+ bne memory_copy_loop
+memory_copy_done:
+ bx lr
+
+
+crt0_memory_set:
+ cmp r0, r1
+ beq memory_set_done
+ strb r2, [r0]
+ add r0, r0, #1
+ b crt0_memory_set
+memory_set_done:
+ bx lr
+
+
+ /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */
+ .section .stack, "wa", %nobits
+ .section .stack_process, "wa", %nobits
+ .section .heap, "wa", %nobits
+ \ No newline at end of file
diff --git a/ports_module/cortex_m4/gnu/example_build/cortexm_vectors.S b/ports_module/cortex_m4/gnu/example_build/cortexm_vectors.S
new file mode 100644
index 00000000..6ae558e4
--- /dev/null
+++ b/ports_module/cortex_m4/gnu/example_build/cortexm_vectors.S
@@ -0,0 +1,77 @@
+ .global reset_handler
+
+ .global __tx_NMIHandler
+ .global __tx_BadHandler
+ .global __tx_SVCallHandler
+ .global __tx_DBGHandler
+ .global __tx_PendSVHandler
+ .global __tx_SysTickHandler
+ .global __tx_BadHandler
+
+ .syntax unified
+ .section .vectors, "ax"
+ .code 16
+ .align 0
+ .global _vectors
+
+_vectors:
+ .word __stack_end__
+ .word reset_handler
+ .word __tx_NMIHandler
+ .word __tx_HardfaultHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word 0 // Reserved
+ .word __tx_SVCallHandler //_SVC_Handler - used by Threadx scheduler //
+ .word __tx_DBGHandler
+ .word 0 // Reserved
+ .word __tx_PendSVHandler
+ .word __tx_SysTickHandler // Used by Threadx timer functionality
+ .word __tx_BadHandler // Populate with user Interrupt handler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+ .word __tx_BadHandler
+
+ .section .init, "ax"
+ .thumb_func
+reset_handler:
+ // low level hardware config, such as PLL setup goes here
+ b _start
+
+
+
diff --git a/ports_module/cortex_m4/gnu/inc/txm_module_port.h b/ports_module/cortex_m4/gnu/inc/txm_module_port.h
index f48c9620..3cb14d4f 100644
--- a/ports_module/cortex_m4/gnu/inc/txm_module_port.h
+++ b/ports_module/cortex_m4/gnu/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M4/GNU */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -376,6 +433,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/GNU Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/GNU Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
index 948b153c..4d5e9947 100644
--- a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -588,14 +602,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m4/gnu/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m4/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
index dcc8d2aa..36127034 100644
--- a/ports_module/cortex_m4/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m4/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M4 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m4/iar/inc/txm_module_port.h b/ports_module/cortex_m4/iar/inc/txm_module_port.h
index d02fb1ad..e92cfc0f 100644
--- a/ports_module/cortex_m4/iar/inc/txm_module_port.h
+++ b/ports_module/cortex_m4/iar/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M4/IAR */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -112,6 +115,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -377,6 +434,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/IAR Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M4/IAR Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s
index 92840961..8291f334 100644
--- a/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s
@@ -28,6 +28,7 @@
EXTERN _tx_thread_preempt_disable
EXTERN _txm_module_manager_memory_fault_handler
EXTERN _txm_module_manager_memory_fault_info
+ EXTERN txm_module_default_mpu_registers
SECTION `.text`:CODE:NOROOT(2)
THUMB
@@ -36,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M4/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -72,6 +73,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +390,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,14 +424,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARMVFP__
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -574,14 +589,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c
index dcc8d2aa..36127034 100644
--- a/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m4/iar/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M4 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m7/ac5/inc/txm_module_port.h b/ports_module/cortex_m7/ac5/inc/txm_module_port.h
index e7a4e826..3ac5acf7 100644
--- a/ports_module/cortex_m7/ac5/inc/txm_module_port.h
+++ b/ports_module/cortex_m7/ac5/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M7/AC5 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
diff --git a/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s
index 150f9818..21b92ae7 100644
--- a/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/AC5 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -76,6 +76,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +389,33 @@ __tx_ts_restore
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,6 +423,7 @@ __tx_ts_restore
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
@@ -420,6 +432,7 @@ _tx_enable_mpu
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __TARGET_FPU_VFP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -573,14 +586,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
index bfffa5bc..55369436 100644
--- a/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m7/ac5/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M7 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m7/ac6/inc/txm_module_port.h b/ports_module/cortex_m7/ac6/inc/txm_module_port.h
index 1fd6ce26..e1cce9ca 100644
--- a/ports_module/cortex_m7/ac6/inc/txm_module_port.h
+++ b/ports_module/cortex_m7/ac6/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M7/AC6 */
-/* 6.1.10 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -44,6 +44,9 @@
/* 01-31-2022 Scott Larson Modified comments and made */
/* heap user-configurable, */
/* resulting in version 6.1.10 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -119,6 +122,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -384,6 +441,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/AC6 Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/AC6 Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c b/ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c
index cf2cc166..a5c1cc72 100644
--- a/ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c
+++ b/ports_module/cortex_m7/ac6/module_lib/src/txm_module_thread_shell_entry.c
@@ -57,7 +57,7 @@ extern VOID _txm_module_initialize(VOID *heap_base, VOID *heap_top);
/* FUNCTION RELEASE */
/* */
/* _txm_module_thread_shell_entry Cortex-M7/AC6 */
-/* 6.1.10 */
+/* 6.1.10 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
diff --git a/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S
index c6b66e54..7111ccf1 100644
--- a/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S
@@ -42,7 +42,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/AC6 */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
diff --git a/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
index bfffa5bc..55369436 100644
--- a/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m7/ac6/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M7 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m7/gnu/inc/txm_module_port.h b/ports_module/cortex_m7/gnu/inc/txm_module_port.h
index 8731adfe..ba3b3ec0 100644
--- a/ports_module/cortex_m7/gnu/inc/txm_module_port.h
+++ b/ports_module/cortex_m7/gnu/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M7/GNU */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -111,6 +114,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -376,6 +433,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/GNU Version 6.1.9 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/GNU Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S
index e3401782..69cb74bb 100644
--- a/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S
+++ b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S
@@ -40,7 +40,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/GNU */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -78,6 +78,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -398,26 +402,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -425,14 +436,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARM_FP
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -588,14 +602,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
index bfffa5bc..55369436 100644
--- a/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m7/gnu/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M7 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_m7/iar/inc/txm_module_port.h b/ports_module/cortex_m7/iar/inc/txm_module_port.h
index 153d6604..32103d56 100644
--- a/ports_module/cortex_m7/iar/inc/txm_module_port.h
+++ b/ports_module/cortex_m7/iar/inc/txm_module_port.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* txm_module_port.h Cortex-M7/IAR */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -41,6 +41,9 @@
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enabled user-defined and */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
@@ -112,6 +115,60 @@ The following extensions must also be defined in tx_port.h:
#define TXM_MODULE_MPU_SHARED_ACCESS_CONTROL 0x12070000
#endif
+/* For Cortex-M devices with 16 MPU regions, the last four regions (12-15)
+ are not used by ThreadX. These may be defined by the user. */
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_12 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_13 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_14 0
+#define TXM_MODULE_MPU_USER_DEFINED_RBAR_15 0
+#define TXM_MODULE_MPU_USER_DEFINED_RASR_15 0
+
+
+/* Users can define these default MPU configuration values.
+
+ If TXM_MODULE_MPU_DEFAULT is *not* defined, the MPU is disabled
+ when a thread that is not owned by a module is running
+ and the defines below are not used.
+
+ If TXM_MODULE_MPU_DEFAULT is defined, the MPU is configured to the
+ below values when a thread that is not owned by a module is running. */
+#define TXM_MODULE_MPU_DEFAULT_RBAR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_0 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_1 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_2 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_3 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_4 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_5 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_6 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_7 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_8 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_9 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_10 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_11 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_12 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_13 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_14 0
+#define TXM_MODULE_MPU_DEFAULT_RBAR_15 0
+#define TXM_MODULE_MPU_DEFAULT_RASR_15 0
+
+
/* Define constants specific to the tools the module can be built with for this particular modules port. */
#define TXM_MODULE_IAR_COMPILER 0x00000000
@@ -377,6 +434,6 @@ UINT _txm_module_manager_inside_data_check(TXM_MODULE_INSTANCE *module_instance
#define TXM_MODULE_MANAGER_VERSION_ID \
CHAR _txm_module_manager_version_id[] = \
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/IAR Version 6.1.10 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Module Cortex-M7/IAR Version 6.1.12 *";
#endif
diff --git a/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s
index 2d66551f..632b507c 100644
--- a/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s
+++ b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s
@@ -28,6 +28,7 @@
EXTERN _tx_thread_preempt_disable
EXTERN _txm_module_manager_memory_fault_handler
EXTERN _txm_module_manager_memory_fault_info
+ EXTERN txm_module_default_mpu_registers
SECTION `.text`:CODE:NOROOT(2)
THUMB
@@ -36,7 +37,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule Cortex-M7/IAR */
-/* 6.1.11 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -72,6 +73,10 @@
/* 04-25-2022 Scott Larson Optimized MPU configuration, */
/* added BASEPRI support, */
/* resulting in version 6.1.11 */
+/* 07-29-2022 Scott Larson Removed the code path to skip */
+/* MPU reloading, optional */
+/* default MPU settings, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
// VOID _tx_thread_schedule(VOID)
@@ -385,26 +390,33 @@ __tx_ts_restore:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r3, #0 // Build disable value
+ CPSID i // Disable interrupts
STR r3, [r0] // Disable MPU
LDR r0, [r1, #0x90] // Pickup the module instance pointer
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r0, default_mpu // Is this thread owned by a module? No, default MPU setup
+#else
CBZ r0, skip_mpu_setup // Is this thread owned by a module? No, skip MPU setup
-
+#endif
+
LDR r2, [r0, #0x8C] // Pickup MPU region 5 address
+#ifdef TXM_MODULE_MPU_DEFAULT
+ CBZ r2, default_mpu // Is protection required for this module? No, default MPU setup
+#else
CBZ r2, skip_mpu_setup // Is protection required for this module? No, skip MPU setup
-
- // Is the MPU already set up for this module?
- MOV r1, #5 // Select region 5 from MPU
- LDR r3, =0xE000ED98 // MPU_RNR register address
- STR r1, [r3] // Set region to 5
+#endif
LDR r1, =0xE000ED9C // MPU_RBAR register address
- LDR r3, [r1] // Load address stored in MPU region 5
- BIC r2, r2, #0x10 // Clear VALID bit
- CMP r2, r3 // Is module already loaded?
- BEQ _tx_enable_mpu // Yes - skip MPU reconfiguration
// Use alias registers to quickly load MPU
ADD r0, r0, #100 // Build address of MPU register start in thread control block
+#ifdef TXM_MODULE_MPU_DEFAULT
+ B config_mpu // configure MPU for module
+default_mpu:
+ LDR r0, =txm_module_default_mpu_registers // default MPU configuration
+#endif
+
+config_mpu:
LDM r0!,{r2-r9} // Load MPU regions 0-3
STM r1,{r2-r9} // Store MPU regions 0-3
LDM r0!,{r2-r9} // Load MPU regions 4-7
@@ -412,14 +424,17 @@ __tx_ts_restore:
#ifdef TXM_MODULE_MANAGER_16_MPU
LDM r0!,{r2-r9} // Load MPU regions 8-11
STM r1,{r2-r9} // Store MPU regions 8-11
+ // Regions 12-15 are reserved for the user to define.
LDM r0,{r2-r9} // Load MPU regions 12-15
STM r1,{r2-r9} // Store MPU regions 12-15
#endif
+
_tx_enable_mpu:
LDR r0, =0xE000ED94 // Build MPU control reg address
MOV r1, #5 // Build enable value with background region enabled
STR r1, [r0] // Enable MPU
skip_mpu_setup:
+ CPSIE i // Enable interrupts
LDMIA r12!, {LR} // Pickup LR
#ifdef __ARMVFP__
TST LR, #0x10 // Determine if the VFP extended frame is present
@@ -574,14 +589,14 @@ _tx_no_lazy_clear:
#endif
/* Copy kernel hardware stack to module thread stack. */
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
- LDM r3!, {r1-r2}
- STM r0!, {r1-r2}
+ LDM r3!, {r1-r2} // Get r0, r1 from kernel stack
+ STM r0!, {r1-r2} // Insert r0, r1 into thread stack
+ LDM r3!, {r1-r2} // Get r2, r3 from kernel stack
+ STM r0!, {r1-r2} // Insert r2, r3 into thread stack
+ LDM r3!, {r1-r2} // Get r12, lr from kernel stack
+ STM r0!, {r1-r2} // Insert r12, lr into thread stack
+ LDM r3!, {r1-r2} // Get pc, xpsr from kernel stack
+ STM r0!, {r1-r2} // Insert pc, xpsr into thread stack
SUB r0, r0, #32 // Subtract 32 to get back to top of stack
MSR PSP, r0 // Set thread stack pointer
diff --git a/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c
index bfffa5bc..55369436 100644
--- a/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c
+++ b/ports_module/cortex_m7/iar/module_manager/src/txm_module_manager_mm_register_setup.c
@@ -25,6 +25,43 @@
#include "tx_api.h"
#include "txm_module.h"
+#ifdef TXM_MODULE_MPU_DEFAULT
+const ULONG txm_module_default_mpu_registers[32] =
+ {
+ TXM_MODULE_MPU_DEFAULT_RBAR_0,
+ TXM_MODULE_MPU_DEFAULT_RASR_0,
+ TXM_MODULE_MPU_DEFAULT_RBAR_1,
+ TXM_MODULE_MPU_DEFAULT_RASR_1,
+ TXM_MODULE_MPU_DEFAULT_RBAR_2,
+ TXM_MODULE_MPU_DEFAULT_RASR_2,
+ TXM_MODULE_MPU_DEFAULT_RBAR_3,
+ TXM_MODULE_MPU_DEFAULT_RASR_3,
+ TXM_MODULE_MPU_DEFAULT_RBAR_4,
+ TXM_MODULE_MPU_DEFAULT_RASR_4,
+ TXM_MODULE_MPU_DEFAULT_RBAR_5,
+ TXM_MODULE_MPU_DEFAULT_RASR_5,
+ TXM_MODULE_MPU_DEFAULT_RBAR_6,
+ TXM_MODULE_MPU_DEFAULT_RASR_6,
+ TXM_MODULE_MPU_DEFAULT_RBAR_7,
+ TXM_MODULE_MPU_DEFAULT_RASR_7,
+ TXM_MODULE_MPU_DEFAULT_RBAR_8,
+ TXM_MODULE_MPU_DEFAULT_RASR_8,
+ TXM_MODULE_MPU_DEFAULT_RBAR_9,
+ TXM_MODULE_MPU_DEFAULT_RASR_9,
+ TXM_MODULE_MPU_DEFAULT_RBAR_10,
+ TXM_MODULE_MPU_DEFAULT_RASR_10,
+ TXM_MODULE_MPU_DEFAULT_RBAR_11,
+ TXM_MODULE_MPU_DEFAULT_RASR_11,
+ TXM_MODULE_MPU_DEFAULT_RBAR_12,
+ TXM_MODULE_MPU_DEFAULT_RASR_12,
+ TXM_MODULE_MPU_DEFAULT_RBAR_13,
+ TXM_MODULE_MPU_DEFAULT_RASR_13,
+ TXM_MODULE_MPU_DEFAULT_RBAR_14,
+ TXM_MODULE_MPU_DEFAULT_RASR_14,
+ TXM_MODULE_MPU_DEFAULT_RBAR_15,
+ TXM_MODULE_MPU_DEFAULT_RASR_15
+ };
+#endif
/**************************************************************************/
/* */
@@ -231,7 +268,7 @@ UINT srd_bit_index;
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_mm_register_setup Cortex-M7 */
-/* 6.1.9 */
+/* 6.1.12 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -267,10 +304,10 @@ UINT srd_bit_index;
/* 9 Module shared memory region */
/* 10 Module shared memory region */
/* 11 Module shared memory region */
-/* 12 Unused region */
-/* 13 Unused region */
-/* 14 Unused region */
-/* 15 Unused region */
+/* 12 User-defined region */
+/* 13 User-defined region */
+/* 14 User-defined region */
+/* 15 User-defined region */
/* */
/* */
/* INPUT */
@@ -294,6 +331,8 @@ UINT srd_bit_index;
/* DATE NAME DESCRIPTION */
/* */
/* 10-15-2021 Scott Larson Initial Version 6.1.9 */
+/* 07-29-2022 Scott Larson Enable user defined regions, */
+/* resulting in version 6.1.12 */
/* */
/**************************************************************************/
VOID _txm_module_manager_mm_register_setup(TXM_MODULE_INSTANCE *module_instance)
@@ -456,18 +495,18 @@ UINT i;
/* Increment MPU table index. */
mpu_table_index++;
}
-
- /* Setup MPU for the remaining regions. */
- while (mpu_table_index < TXM_MODULE_MPU_TOTAL_ENTRIES)
- {
- /* Build the base address register with address, MPU region, set Valid bit. */
- module_instance -> txm_module_instance_mpu_registers[mpu_table_index].txm_module_mpu_region_address = mpu_table_index | 0x10;
-
- /* Increment MPU table index. */
- mpu_table_index++;
- }
-#else
+ /* Setup user-defined regions (12-15). */
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_12;
+ module_instance -> txm_module_instance_mpu_registers[12].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_12;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_13;
+ module_instance -> txm_module_instance_mpu_registers[13].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_13;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_14;
+ module_instance -> txm_module_instance_mpu_registers[14].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_14;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_address = TXM_MODULE_MPU_USER_DEFINED_RBAR_15;
+ module_instance -> txm_module_instance_mpu_registers[15].txm_module_mpu_region_attribute_size = TXM_MODULE_MPU_USER_DEFINED_RASR_15;
+
+#else /* TXM_MODULE_MANAGER_16_MPU is not defined, only 8 MPU regions. */
ULONG code_address;
ULONG code_size;
diff --git a/ports_module/cortex_r4/ac6/example_build/sample_threadx/.cproject b/ports_module/cortex_r4/ac6/example_build/sample_threadx/.cproject
new file mode 100644
index 00000000..71818fd9
--- /dev/null
+++ b/ports_module/cortex_r4/ac6/example_build/sample_threadx/.cproject
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
+
+ <storageModule moduleId="org.eclipse.cdt.core.settings">
+
+ <cconfiguration id="com.arm.eclipse.build.config.v6.exe.debug.base.1352491235">
+
+ <storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.exe.debug.base.1352491235" moduleId="org.eclipse.cdt.core.settings" name="Debug">
+
+ <externalSettings/>
+
+ <extensions>
+
+ <extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
+
+ <extension id="com.arm.eclipse.builder.armcc.error" point="org.eclipse.cdt.core.ErrorParser"/>
+
+ <extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
+
+ </extensions>
+
+ </storageModule>
+
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+
+ <configuration artifactExtension="axf" artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe,org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug" cleanCommand="clean" description="" id="com.arm.eclipse.build.config.v6.exe.debug.base.1352491235" name="Debug" parent="com.arm.eclipse.build.config.v6.exe.debug.base">
+
+ <folderInfo id="com.arm.eclipse.build.config.v6.exe.debug.base.1352491235." name="/" resourcePath="">
+
+ <toolChain id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.804641625" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6">
+
+ <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1862712116" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" value="Cortex-R4.VFPv3_D16" valueType="string"/>
+
+ <option id="com.arm.toolchain.v6.base.options.floatabi.601947014" name="Float ABI" superClass="com.arm.toolchain.v6.base.options.floatabi" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
+
+ <option id="com.arm.toolchain.v6.base.options.inst.1204023733" name="Instruction set" superClass="com.arm.toolchain.v6.base.options.inst" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
+
+ <option id="com.arm.toolchain.v6.base.options.debug.level.818353536" name="Debug Level" superClass="com.arm.toolchain.v6.base.options.debug.level" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
+
+ <targetPlatform id="com.arm.toolchain.v6.exe.debug.base.var.arm_compiler_6-6.804641625.385562723" name=""/>
+
+ <builder autoBuildTarget="all" buildPath="${workspace_loc:/sample_threadx_module_manager}/Debug" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="com.arm.toolchain.v6.builder.1941932380" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="8" superClass="com.arm.toolchain.v6.builder"/>
+
+ <tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.31312115" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6">
+
+ <option id="com.arm.tool.c.compiler.v6.base.option.target.1871497465" name="Target (--target)" superClass="com.arm.tool.c.compiler.v6.base.option.target" useByScannerDiscovery="true" value="arm-arm-none-eabi" valueType="string"/>
+
+ <option id="com.arm.tool.c.compiler.v6.base.option.cpu.582298517" name="CPU (-mcpu)" superClass="com.arm.tool.c.compiler.v6.base.option.cpu" useByScannerDiscovery="true" value="cortex-r4f" valueType="string"/>
+
+ <option id="com.arm.tool.c.compiler.v6.base.option.fpu.2077436824" name="FPU (-mfpu)" superClass="com.arm.tool.c.compiler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
+
+ <option id="com.arm.tool.c.compiler.v6.base.option.floatabi.1440514949" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.c.compiler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
+
+ <option id="com.arm.tool.c.compiler.v6.base.option.inst.1725781447" name="Instruction set" superClass="com.arm.tool.c.compiler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
+
+ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.compiler.v6.base.option.incpath.1999415170" name="Include path (-I)" superClass="com.arm.tool.c.compiler.v6.base.option.incpath" useByScannerDiscovery="false" valueType="includePath">
+
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_port}&quot;"/>
+
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_generic}&quot;"/>
+
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/inc_generic_modules}&quot;"/>
+
+ </option>
+
+ <option id="com.arm.tool.c.compiler.v6.base.options.debug.level.1853971560" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
+
+ <inputType id="com.arm.tool.c.compiler.v6.base.input.1194689224" superClass="com.arm.tool.c.compiler.v6.base.input"/>
+
+ </tool>
+
+ <tool id="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6.1028636576" name="Arm C++ Compiler 6" superClass="com.arm.tool.cpp.compiler.v6.base.var.arm_compiler_6-6">
+
+ <option id="com.arm.tool.c.compiler.v6.base.options.debug.level.528092979" name="Debug Level" superClass="com.arm.tool.c.compiler.v6.base.options.debug.level" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.options.debug.level.std" valueType="enumerated"/>
+
+ </tool>
+
+ <tool id="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6.2084155435" name="Arm Assembler 6" superClass="com.arm.tool.assembler.v6.base.var.arm_compiler_6-6">
+
+ <option id="com.arm.tool.assembler.v6.base.option.target.1360157853" name="Target (--target)" superClass="com.arm.tool.assembler.v6.base.option.target" useByScannerDiscovery="false" value="arm-arm-none-eabi" valueType="string"/>
+
+ <option id="com.arm.tool.assembler.v6.base.option.cpu.1037858246" name="CPU (-mcpu)" superClass="com.arm.tool.assembler.v6.base.option.cpu" useByScannerDiscovery="false" value="cortex-r4f" valueType="string"/>
+
+ <option id="com.arm.tool.assembler.v6.base.option.fpu.1926125524" name="FPU (-mfpu)" superClass="com.arm.tool.assembler.v6.base.option.fpu" useByScannerDiscovery="true" value="vfpv3-d16" valueType="string"/>
+
+ <option id="com.arm.tool.assembler.v6.base.option.floatabi.8023587" name="Float ABI (-mfloat-abi)" superClass="com.arm.tool.assembler.v6.base.option.floatabi" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.floatabi.soft" valueType="enumerated"/>
+
+ <option id="com.arm.tool.assembler.v6.base.option.inst.661293084" name="Instruction set" superClass="com.arm.tool.assembler.v6.base.option.inst" useByScannerDiscovery="true" value="com.arm.tool.c.compiler.v6.base.option.inst.arm" valueType="enumerated"/>
+
+ <option id="com.arm.tool.assembler.v6.base.options.debug.level.460302808" name="Debug Level" superClass="com.arm.tool.assembler.v6.base.options.debug.level" useByScannerDiscovery="false" value="com.arm.tool.assembler.v6.base.options.debug.level.std" valueType="enumerated"/>
+
+ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.arm.tool.assembler.v6.base.option.incpath.2020985046" name="Include path (-I)" superClass="com.arm.tool.assembler.v6.base.option.incpath" valueType="includePath"/>
+
+ <inputType id="com.arm.tool.assembler.v6.base.input.343891542" superClass="com.arm.tool.assembler.v6.base.input"/>
+
+ </tool>
+
+ <tool id="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6.831136805" name="Arm Linker 6" superClass="com.arm.tool.c.linker.v6.base.var.arm_compiler_6-6">
+
+ <option id="com.arm.tool.c.linker.option.entry.1475419086" name="Image entry point (--entry)" superClass="com.arm.tool.c.linker.option.entry" useByScannerDiscovery="false" value="Vectors" valueType="string"/>
+
+ <option id="com.arm.tool.c.linker.option.scatter.1811442260" name="Scatter file (--scatter)" superClass="com.arm.tool.c.linker.option.scatter" useByScannerDiscovery="false" value="../sample_threadx.scat" valueType="string"/>
+
+ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="com.arm.tool.c.linker.libs.2083701191" name="User library files" superClass="com.arm.tool.c.linker.libs" useByScannerDiscovery="false" valueType="libs"/>
+
+ <option id="com.arm.tool.c.linker.option.imagemap.1405130028" name="Generate image map (--map)" superClass="com.arm.tool.c.linker.option.imagemap" useByScannerDiscovery="false" value="true" valueType="boolean"/>
+
+ <option id="com.arm.tool.c.linker.option.sizes.1951623263" name="List code and data sizes of output image (--info=sizes)" superClass="com.arm.tool.c.linker.option.sizes" useByScannerDiscovery="false" value="false" valueType="boolean"/>
+
+ <option id="com.arm.tool.c.linker.option.redirectoutput.1115886571" name="Redirect diagnostics output to file (--list)" superClass="com.arm.tool.c.linker.option.redirectoutput" useByScannerDiscovery="false" value="map.map" valueType="string"/>
+
+ <option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="com.arm.tool.c.linker.implicit.libs.790772204" name="Implicit other library files" superClass="com.arm.tool.c.linker.implicit.libs" valueType="libs">
+
+ <listOptionValue builtIn="false" value="&quot;${workspace_loc:/tx/Debug/tx.a}&quot;"/>
+
+ </option>
+
+ </tool>
+
+ <tool id="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6.552129599" name="Arm Librarian 6" superClass="com.arm.tool.librarian.v6.base.var.arm_compiler_6-6"/>
+
+ </toolChain>
+
+ </folderInfo>
+
+ </configuration>
+
+ </storageModule>
+
+ <storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
+
+ </cconfiguration>
+
+ </storageModule>
+
+ <storageModule moduleId="cdtBuildSystem" version="4.0.0">
+
+ <project id="sample_threadx.com.arm.eclipse.build.project.v6.exe.1139105725" name="Executable"/>
+
+ </storageModule>
+
+ <storageModule moduleId="scannerConfiguration">
+
+ <autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
+
+ </storageModule>
+
+ <storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
+
+ <storageModule moduleId="com.arm.projectSettings" version="6.0.0"/>
+
+ <storageModule moduleId="refreshScope" versionNumber="2">
+
+ <configuration configurationName="Debug">
+
+ <resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
+
+ </configuration>
+
+ <configuration configurationName="Release">
+
+ <resource resourceType="PROJECT" workspacePath="/sample_threadx"/>
+
+ </configuration>
+
+ </storageModule>
+
+ <storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
+
+</cproject>
diff --git a/ports_module/cortex_r4/ac6/example_build/sample_threadx/.project b/ports_module/cortex_r4/ac6/example_build/sample_threadx/.project
new file mode 100644
index 00000000..a1b15572
--- /dev/null
+++ b/ports_module/cortex_r4/ac6/example_build/sample_threadx/.project
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>sample_threadx</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
+ <triggers>clean,full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
+ <triggers>full,incremental,</triggers>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.cdt.core.cnature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
+ <nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
+ </natures>
+</projectDescription>
diff --git a/ports_module/cortex_r4/ac6/example_build/sample_threadx/sample_threadx.c b/ports_module/cortex_r4/ac6/example_build/sample_threadx/sample_threadx.c
new file mode 100644
index 00000000..4a677059
--- /dev/null
+++ b/ports_module/cortex_r4/ac6/example_build/sample_threadx/sample_threadx.c
@@ -0,0 +1,374 @@
+/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight
+ threads of different priorities, using a message queue, semaphore, mutex, event flags group,
+ byte pool, and block pool. */
+
+#include "tx_api.h"
+#include "timer.h"
+
+#define DEMO_STACK_SIZE 1024
+#define DEMO_BYTE_POOL_SIZE 9120
+#define DEMO_BLOCK_POOL_SIZE 100
+#define DEMO_QUEUE_SIZE 100
+
+
+/* Define the ThreadX object control blocks... */
+
+TX_THREAD thread_0;
+TX_THREAD thread_1;
+TX_THREAD thread_2;
+TX_THREAD thread_3;
+TX_THREAD thread_4;
+TX_THREAD thread_5;
+TX_THREAD thread_6;
+TX_THREAD thread_7;
+TX_QUEUE queue_0;
+TX_SEMAPHORE semaphore_0;
+TX_MUTEX mutex_0;
+TX_EVENT_FLAGS_GROUP event_flags_0;
+TX_BYTE_POOL byte_pool_0;
+TX_BLOCK_POOL block_pool_0;
+UCHAR memory_area[DEMO_BYTE_POOL_SIZE];
+
+
+/* Define the counters used in the demo application... */
+
+ULONG thread_0_counter;
+ULONG thread_1_counter;
+ULONG thread_1_messages_sent;
+ULONG thread_2_counter;
+ULONG thread_2_messages_received;
+ULONG thread_3_counter;
+ULONG thread_4_counter;
+ULONG thread_5_counter;
+ULONG thread_6_counter;
+ULONG thread_7_counter;
+
+
+/* Define thread prototypes. */
+
+void thread_0_entry(ULONG thread_input);
+void thread_1_entry(ULONG thread_input);
+void thread_2_entry(ULONG thread_input);
+void thread_3_and_4_entry(ULONG thread_input);
+void thread_5_entry(ULONG thread_input);
+void thread_6_and_7_entry(ULONG thread_input);
+
+
+/* Define main entry point. */
+
+int main()
+{
+
+ /* Setup the timer. */
+ timer_init();
+
+ /* Enter the ThreadX kernel. */
+ tx_kernel_enter();
+}
+
+
+/* Define what the initial system looks like. */
+
+void tx_application_define(void *first_unused_memory)
+{
+
+CHAR *pointer = TX_NULL;
+
+
+ /* Create a byte memory pool from which to allocate the thread stacks. */
+ tx_byte_pool_create(&byte_pool_0, "byte pool 0", memory_area, DEMO_BYTE_POOL_SIZE);
+
+ /* Put system definition stuff in here, e.g. thread creates and other assorted
+ create information. */
+
+ /* Allocate the stack for thread 0. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create the main thread. */
+ tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
+ pointer, DEMO_STACK_SIZE,
+ 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+
+ /* Allocate the stack for thread 1. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 1 and 2. These threads pass information through a ThreadX
+ message queue. It is also interesting to note that these threads have a time
+ slice. */
+ tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,
+ pointer, DEMO_STACK_SIZE,
+ 16, 16, 4, TX_AUTO_START);
+
+ /* Allocate the stack for thread 2. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
+ pointer, DEMO_STACK_SIZE,
+ 16, 16, 4, TX_AUTO_START);
+
+ /* Allocate the stack for thread 3. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore.
+ An interesting thing here is that both threads share the same instruction area. */
+ tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 4. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 5. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create thread 5. This thread simply pends on an event flag which will be set
+ by thread_0. */
+ tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,
+ pointer, DEMO_STACK_SIZE,
+ 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 6. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */
+ tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the stack for thread 7. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
+
+ tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,
+ pointer, DEMO_STACK_SIZE,
+ 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);
+
+ /* Allocate the message queue. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);
+
+ /* Create the message queue shared by threads 1 and 2. */
+ tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));
+
+ /* Create the semaphore used by threads 3 and 4. */
+ tx_semaphore_create(&semaphore_0, "semaphore 0", 1);
+
+ /* Create the event flags group used by threads 1 and 5. */
+ tx_event_flags_create(&event_flags_0, "event flags 0");
+
+ /* Create the mutex used by thread 6 and 7 without priority inheritance. */
+ tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);
+
+ /* Allocate the memory for a small block pool. */
+ tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);
+
+ /* Create a block memory pool to allocate a message buffer from. */
+ tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);
+
+ /* Allocate a block and release the block memory. */
+ tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);
+
+ /* Release the block back to the pool. */
+ tx_block_release(pointer);
+}
+
+
+
+/* Define the test threads. */
+
+void thread_0_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This thread simply sits in while-forever-sleep loop. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_0_counter++;
+
+ /* Sleep for 10 ticks. */
+ tx_thread_sleep(10);
+
+ /* Set event flag 0 to wakeup thread 5. */
+ status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+void thread_1_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This thread simply sends messages to a queue shared by thread 2. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_1_counter++;
+
+ /* Send message to queue 0. */
+ status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER);
+
+ /* Check completion status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Increment the message sent. */
+ thread_1_messages_sent++;
+ }
+}
+
+
+void thread_2_entry(ULONG thread_input)
+{
+
+ULONG received_message;
+UINT status;
+
+ /* This thread retrieves messages placed on the queue by thread 1. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_2_counter++;
+
+ /* Retrieve a message from the queue. */
+ status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER);
+
+ /* Check completion status and make sure the message is what we
+ expected. */
+ if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received))
+ break;
+
+ /* Otherwise, all is okay. Increment the received message count. */
+ thread_2_messages_received++;
+ }
+}
+
+
+void thread_3_and_4_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This function is executed from thread 3 and thread 4. As the loop
+ below shows, these function compete for ownership of semaphore_0. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ if (thread_input == 3)
+ thread_3_counter++;
+ else
+ thread_4_counter++;
+
+ /* Get the semaphore with suspension. */
+ status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Sleep for 2 ticks to hold the semaphore. */
+ tx_thread_sleep(2);
+
+ /* Release the semaphore. */
+ status = tx_semaphore_put(&semaphore_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
+
+
+void thread_5_entry(ULONG thread_input)
+{
+
+UINT status;
+ULONG actual_flags;
+
+
+ /* This thread simply waits for an event in a forever loop. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ thread_5_counter++;
+
+ /* Wait for event flag 0. */
+ status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR,
+ &actual_flags, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if ((status != TX_SUCCESS) || (actual_flags != 0x1))
+ break;
+ }
+}
+
+
+void thread_6_and_7_entry(ULONG thread_input)
+{
+
+UINT status;
+
+
+ /* This function is executed from thread 6 and thread 7. As the loop
+ below shows, these function compete for ownership of mutex_0. */
+ while(1)
+ {
+
+ /* Increment the thread counter. */
+ if (thread_input == 6)
+ thread_6_counter++;
+ else
+ thread_7_counter++;
+
+ /* Get the mutex with suspension. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Get the mutex again with suspension. This shows
+ that an owning thread may retrieve the mutex it
+ owns multiple times. */
+ status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Sleep for 2 ticks to hold the mutex. */
+ tx_thread_sleep(2);
+
+ /* Release the mutex. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+
+ /* Release the mutex again. This will actually
+ release ownership since it was obtained twice. */
+ status = tx_mutex_put(&mutex_0);
+
+ /* Check status. */
+ if (status != TX_SUCCESS)
+ break;
+ }
+}
diff --git a/ports_module/cortex_r4/ac6/example_build/sample_threadx/tx_cortex_r4.launch b/ports_module/cortex_r4/ac6/example_build/sample_threadx/tx_cortex_r4.launch
new file mode 100644
index 00000000..4d4f7ba9
--- /dev/null
+++ b/ports_module/cortex_r4/ac6/example_build/sample_threadx/tx_cortex_r4.launch
@@ -0,0 +1,469 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<launchConfiguration type="com.arm.debugger.launcher2">
+ <mapAttribute key="AverageDurationTracker">
+ <mapEntry key="*Fetching Data" value="24001419"/>
+ <mapEntry key="*Fetching Data Model" value="837547"/>
+ <mapEntry key="*FunctionLoader" value="60205600"/>
+ <mapEntry key="*list global low level symbols" value="1092807"/>
+ <mapEntry key="*loading memory from target" value="1956885"/>
+ <mapEntry key="*loading values from target" value="5548004"/>
+ <mapEntry key="*trace" value="357936340"/>
+ <mapEntry key="*updating expressions" value="14485737"/>
+ <mapEntry key="*updating local_variables" value="491765"/>
+ <mapEntry key="*updating registers" value="15501822"/>
+ <mapEntry key="*updating variables" value="1347961"/>
+ <mapEntry key="AddEventObserver" value="2496890"/>
+ <mapEntry key="Evaluate" value="1471500"/>
+ <mapEntry key="ResumeToHere" value="16558874"/>
+ <mapEntry key="Retrieving globals list" value="25220314"/>
+ <mapEntry key="add-symbol-file" value="11456014"/>
+ <mapEntry key="areCachesAvailable" value="431165"/>
+ <mapEntry key="backtrace" value="8618003"/>
+ <mapEntry key="break" value="3610654"/>
+ <mapEntry key="checking tracepoints" value="41266"/>
+ <mapEntry key="compute execution mode" value="1223800"/>
+ <mapEntry key="console" value="32264250"/>
+ <mapEntry key="continue" value="30184117"/>
+ <mapEntry key="core" value="8098422"/>
+ <mapEntry key="disable" value="2289400"/>
+ <mapEntry key="disassemble" value="47116008"/>
+ <mapEntry key="enable" value="3396700"/>
+ <mapEntry key="evaluate address" value="610217"/>
+ <mapEntry key="finish" value="27225260"/>
+ <mapEntry key="get byte order" value="435704"/>
+ <mapEntry key="get capabilities" value="392784"/>
+ <mapEntry key="get execution addresss" value="1575181"/>
+ <mapEntry key="get source lines" value="795586"/>
+ <mapEntry key="getValidEncodings" value="417981"/>
+ <mapEntry key="initialize command help" value="40341999"/>
+ <mapEntry key="interrupt" value="78867364"/>
+ <mapEntry key="list breakpoint options" value="130971"/>
+ <mapEntry key="list breakpoints" value="326120"/>
+ <mapEntry key="list instruction sets" value="563705"/>
+ <mapEntry key="list signals" value="23953891"/>
+ <mapEntry key="list watchpoint options" value="1543199"/>
+ <mapEntry key="list watchpoints" value="463760"/>
+ <mapEntry key="loadfile" value="101343639"/>
+ <mapEntry key="next" value="19921924"/>
+ <mapEntry key="remove" value="1212473"/>
+ <mapEntry key="run" value="17693094"/>
+ <mapEntry key="run script" value="50680881"/>
+ <mapEntry key="select-frame" value="428835"/>
+ <mapEntry key="set CWD" value="3439986"/>
+ <mapEntry key="set breakpoint properties" value="3050687"/>
+ <mapEntry key="set debug-from" value="937032"/>
+ <mapEntry key="start" value="71393875"/>
+ <mapEntry key="step" value="29909833"/>
+ <mapEntry key="synchronizing trace ranges" value="37797"/>
+ <mapEntry key="target reset" value="5095100"/>
+ <mapEntry key="toggleBreakpoint" value="7565021"/>
+ <mapEntry key="updateBreakpointLocation" value="1629832"/>
+ <mapEntry key="waitForTargetToStop" value="13692545"/>
+ <mapEntry key="write expression" value="9225850"/>
+ </mapAttribute>
+ <intAttribute key="DEBUG_TAB..RESOURCES.COUNT" value="0"/>
+ <intAttribute key="FILES.CONNECT_TO_GDB_SERVER.RESOURCES.COUNT" value="0"/>
+ <intAttribute key="FILES.DEBUG_EXISTING_ANDROID.RESOURCES.COUNT" value="0"/>
+ <listAttribute key="FILES.DEBUG_RESIDENT_ANDROID"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
+ <intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
+ <listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="APPLICATION_ON_TARGET"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
+ <intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
+ <listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
+ <intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
+ <listAttribute key="FILES.DOWNLOAD_DEBUG"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
+ <intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
+ <intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
+ <listAttribute key="FILES.ICE_DEBUG">
+ <listEntry value="ON_DEMAND_LOAD"/>
+ <listEntry value="ALSO_LOAD_SYMBOLS"/>
+ </listAttribute>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx/Debug/sample_threadx.axf}"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.1.TYPE" value="SYMBOLS_FILE"/>
+ <stringAttribute key="FILES.ICE_DEBUG.RESOURCES.1.VALUE" value="${workspace_loc:/sample_threadx_module/Debug/sample_threadx_module.axf}"/>
+ <intAttribute key="FILES.ICE_DEBUG.RESOURCES.COUNT" value="1"/>
+ <listAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE">
+ <listEntry value="ON_DEMAND_LOAD"/>
+ <listEntry value="ALSO_LOAD_SYMBOLS"/>
+ </listAttribute>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.0.VALUE" value=""/>
+ <intAttribute key="FILES.ICE_DEBUG_WITH_ETB_TRACE.RESOURCES.COUNT" value="1"/>
+ <listAttribute key="FILES.ICE_DEBUG_WITH_TRACE">
+ <listEntry value="ON_DEMAND_LOAD"/>
+ <listEntry value="ALSO_LOAD_SYMBOLS"/>
+ </listAttribute>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.TYPE" value="APP_ON_HOST_TO_DOWNLOAD"/>
+ <stringAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.0.VALUE" value=""/>
+ <intAttribute key="FILES.ICE_DEBUG_WITH_TRACE.RESOURCES.COUNT" value="1"/>
+ <stringAttribute key="FILES.SELECTED_DEBUG_OPEATION" value="ICE_DEBUG"/>
+ <stringAttribute key="HOST_WORKING_DIR" value="${workspace_loc}"/>
+ <booleanAttribute key="HOST_WORKING_DIR_USE_DEFAULT" value="true"/>
+ <booleanAttribute key="KEY_COMMANDS_AFTER_CONNECT" value="false"/>
+ <stringAttribute key="KEY_COMMANDS_AFTER_CONNECT_TEXT" value=""/>
+ <booleanAttribute key="KEY_COMMANDS_AS_CONNECT" value="false"/>
+ <intAttribute key="Messages.POST_TRIGGER_CAPTURE_SIZE.getLocalisedValue().FMTrace" value="50"/>
+ <booleanAttribute key="Messages.STOP_ON_TRIGGER.getLocalisedValue().FMTrace" value="false"/>
+ <intAttribute key="POST_TRIGGER_CAPTURE_SIZE.model_streaming_capture_0" value="50"/>
+ <booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
+ <booleanAttribute key="STOP_ON_TRIGGER.model_streaming_capture_0" value="false"/>
+ <stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
+ <booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
+ <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.ExpressionsView">
+ <listEntry value="NODE CACHE VERSION 1"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:*_tx_timer_current_ptr:VALUE:(*_tx_timer_current_ptr)-&gt;tx_timer_internal_list_head"/>
+ <listEntry value="1"/>
+ <listEntry value="element formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:pointer"/>
+ <listEntry value="1"/>
+ <listEntry value="element formatter"/>
+ <listEntry value="Character"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:&amp;pointer[0]"/>
+ <listEntry value="1"/>
+ <listEntry value="element formatter"/>
+ <listEntry value="Character"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[1]:VALUE:(my_module).txm_module_instance_mpu_registers[1].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[2]:VALUE:(my_module).txm_module_instance_mpu_registers[2].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[3]:VALUE:(my_module).txm_module_instance_mpu_registers[3].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[3]:VALUE:(my_module).txm_module_instance_mpu_registers[3].txm_module_mpu_region_attributes"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[4]:VALUE:(my_module).txm_module_instance_mpu_registers[4].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[4]:VALUE:(my_module).txm_module_instance_mpu_registers[4].txm_module_mpu_region_size"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[4]:VALUE:(my_module).txm_module_instance_mpu_registers[4].txm_module_mpu_region_attributes"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[9]:VALUE:(my_module).txm_module_instance_mpu_registers[9].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[5]:VALUE:(my_module).txm_module_instance_mpu_registers[5].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[6]:VALUE:(my_module).txm_module_instance_mpu_registers[6].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[7]:VALUE:(my_module).txm_module_instance_mpu_registers[7].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[7]:VALUE:(my_module).txm_module_instance_mpu_registers[7].txm_module_mpu_region_size"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_mpu_registers:VALUE:(my_module).txm_module_instance_mpu_registers[8]:VALUE:(my_module).txm_module_instance_mpu_registers[8].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:my_module:VALUE:(my_module).txm_module_instance_name"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_dfar"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_dfsr"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_sp"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_r0"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_r1"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_r9"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_txm_module_manager_memory_fault_info:VALUE:(_txm_module_manager_memory_fault_info).txm_module_manager_memory_fault_info_cpsr"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:_tx_thread_current_ptr:VALUE:(_tx_thread_current_ptr)-&gt;tx_thread_id"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:(TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[0]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers-&gt;txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:(TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[1]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[1].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:(TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[2]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[2].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="EXPRESSION_GROUP:Expressions:VALUE:(TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[3]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[3].txm_module_mpu_region_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ </listAttribute>
+ <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.VariableTreeView">
+ <listEntry value="NODE CACHE VERSION 1"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_mm_register_setup.c::_txm_module_manager_mm_register_setup::code_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_mm_register_setup.c::_txm_module_manager_mm_register_setup::data_address"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_mm_register_setup.c::_txm_module_manager_mm_register_setup::block_size"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_mm_register_setup.c::_txm_module_manager_mm_register_setup::base_address_register"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_in_place_load.c::_txm_module_manager_in_place_load::data_start"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_in_place_load.c::_txm_module_manager_in_place_load::module_name"/>
+ <listEntry value="1"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="LOCALS:Locals:VALUE:D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/tx/txm_module_manager_in_place_load.c::_txm_module_manager_in_place_load::memory_ptr"/>
+ <listEntry value="2"/>
+ <listEntry value="formatter"/>
+ <listEntry value="Hexadecimal"/>
+ <listEntry value="element formatter"/>
+ <listEntry value="Character"/>
+ </listAttribute>
+ <booleanAttribute key="VFS_ENABLED" value="true"/>
+ <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
+ <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
+ <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_resume.c&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_resume.c&quot; line=&quot;590&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_resume.c&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_resume.c&quot; line=&quot;590&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;176&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;176&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;159&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;159&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_restore.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_restore.S&quot; line=&quot;151&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_restore.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_restore.S&quot; line=&quot;151&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_save.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_save.S&quot; line=&quot;133&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_save.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_save.S&quot; line=&quot;133&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module_manager/sample_threadx_module_manager.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module_manager\sample_threadx_module_manager.c&quot; line=&quot;94&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module_manager/sample_threadx_module_manager.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module_manager\sample_threadx_module_manager.c&quot; line=&quot;94&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module/sample_threadx_module.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module\sample_threadx_module.c&quot; line=&quot;107&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module/sample_threadx_module.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module\sample_threadx_module.c&quot; line=&quot;107&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/tx/tx_initialize_low_level.S&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\tx\tx_initialize_low_level.S&quot; line=&quot;401&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/sample_threadx_module/sample_threadx_module.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\sample_threadx_module\sample_threadx_module.c&quot; line=&quot;274&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; debugFile=&quot;D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/sample_threadx_module/sample_threadx_module.c&quot; hostFile=&quot;D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\sample_threadx_module\sample_threadx_module.c&quot; line=&quot;274&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;0x0001C46C&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_test/ports_module/cortex-r4/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_test\ports_module\cortex-r4\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;193&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;0x0001C46C&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_test/ports_module/cortex-r4/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_test\ports_module\cortex-r4\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;193&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
+ <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
+ <listEntry value="&lt;Next Instruction&gt;"/>
+ <listEntry value=""/>
+ <listEntry value="&amp;(((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr-&gt;tx_thread_module_instance_ptr)-&gt;txm_module_instance_mpu_registers[3].txm_module_mpu_region_address)"/>
+ <listEntry value="0x101326"/>
+ <listEntry value="$pc"/>
+ <listEntry value="0x229"/>
+ <listEntry value="0x107c"/>
+ <listEntry value="0x22c"/>
+ <listEntry value="0x7cb1"/>
+ <listEntry value="0x7cc4"/>
+ <listEntry value="_tx_thread_shell_entry"/>
+ <listEntry value="0x1021d0"/>
+ <listEntry value="_txm_module_initialize"/>
+ <listEntry value="_txm_module_thread_shell_entry"/>
+ <listEntry value="0x00100000"/>
+ <listEntry value="0x201b8"/>
+ <listEntry value="_tx_thread_schedule"/>
+ <listEntry value="0x100000"/>
+ <listEntry value="0x10000"/>
+ <listEntry value="main"/>
+ </listAttribute>
+ <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
+ <listEntry value="100"/>
+ <listEntry value=""/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ <listEntry value="100"/>
+ </listAttribute>
+ <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.MemoryView.addresses">
+ <listEntry value=""/>
+ <listEntry value="0xB0110000"/>
+ <listEntry value="$sp-72"/>
+ <listEntry value="$sp-64"/>
+ <listEntry value="$sp-65"/>
+ <listEntry value="$sp-68"/>
+ <listEntry value="$sp"/>
+ <listEntry value="0x14480"/>
+ <listEntry value="0x14490"/>
+ <listEntry value="0x14498"/>
+ <listEntry value="0x1e370"/>
+ <listEntry value="0x1e388"/>
+ <listEntry value="0x80221d4"/>
+ <listEntry value="0x1ddc0"/>
+ <listEntry value="0x00021200"/>
+ <listEntry value="0x00021290"/>
+ <listEntry value="0x000237B0"/>
+ <listEntry value="main"/>
+ <listEntry value="0x00100000"/>
+ <listEntry value="0x08020000"/>
+ </listAttribute>
+ <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.MemoryView.ranges">
+ <listEntry value=""/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ <listEntry value="1024"/>
+ </listAttribute>
+ <stringAttribute key="com.arm.debug.views.debugConsole.DebugCommandLine.History" value="set semihosting enabled off;set semihosting enabled on"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-R4"/>
+ <stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
+ <stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
+ <stringAttribute key="config_db_platform_name" value="Arm FVP (Installed with Arm DS) - VE_Cortex_R4"/>
+ <stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
+ <stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp_installedwitharmds_/ve_cortex_r4"/>
+ <stringAttribute key="config_file" value="CDB://../../Arm FVP/VE_Cortex_R4/iris_config.xml"/>
+ <booleanAttribute key="connectOnly" value="false"/>
+ <stringAttribute key="connect_existing_model" value="false"/>
+ <stringAttribute key="debugger.view.DataView.os:DataView" value="rO0ABXNyACtjb20uYXJtLmRlYnVnLnZpZXdzLmRhdGEuRGF0YVZpZXdQcm9wZXJ0aWVzAAAAAAAAAAECAAB4cgAlY29tLmFybS5kZWJ1Zy52aWV3cy5kYXRhLlByb3BlcnR5VHJlZQAAAAAAAAABAwABTAAFbURhdGF0ABNMamF2YS91dGlsL0hhc2hNYXA7eHB3BAAAAAJ0ABJkYXRhYmFzZVByb3BlcnRpZXNzcQB+AAF3BAAAAAF0AAd0aHJlYWR4c3IAK2NvbS5hcm0uZGVidWcudmlld3MuZGF0YS5EYXRhYmFzZVByb3BlcnRpZXMAAAAAAAAAAQIAAHhxAH4AAXcEAAAAA3QABnRhYmxlc3NxAH4AAXcEAAAAAXQAB3RocmVhZHNzcgAoY29tLmFybS5kZWJ1Zy52aWV3cy5kYXRhLlRhYmxlUHJvcGVydGllcwAAAAAAAAABAgAAeHEAfgABdwQAAAAEdAACaWRxAH4AC3QAEGNvbHVtbkF1dG9SZXNpemVzcQB+AAF3BAAAAAp0AAEwdAAEdHJ1ZXQAATFxAH4AEnQAATJxAH4AEnQAATNxAH4AEnQAAi0xcQB+ABJ0AAE0cQB+ABJ0AAE1cQB+ABJ0AAE2cQB+ABJ0AAE3cQB+ABJ0AAE4cQB+ABJ4dAAMY29sdW1uV2lkdGhzc3EAfgABdwQAAAAKdAABMHQAAjYwdAABMXQAAjYzdAABMnQAAjUzdAABM3QAAjc4dAACLTF0AAIyNXQAATR0AAI1OHQAATV0AAI0N3QAATZ0AAI3NnQAATd0AAI3MnQAATh0AAI5MHh0AAZjb25maWd0APlPdXRsaW5lQ29uZmlnMQkxMAktMQlmYWxzZQl0cnVlCTI1CS0xCXRydWUJMAl0cnVlCXRydWUJNjAJLTEJdHJ1ZQkxCXRydWUJdHJ1ZQk2MwktMQl0cnVlCTIJdHJ1ZQl0cnVlCTUzCS0xCXRydWUJMwl0cnVlCXRydWUJNzgJLTEJdHJ1ZQk0CXRydWUJdHJ1ZQk1OAktMQl0cnVlCTUJdHJ1ZQl0cnVlCTQ3CS0xCXRydWUJNgl0cnVlCXRydWUJNzYJLTEJdHJ1ZQk3CXRydWUJdHJ1ZQk3MgktMQl0cnVlCTgJdHJ1ZQl0cnVlCTkwCS0xCXRydWV4eHEAfgAOcQB+AAZ0AAxjdXJyZW50VGFibGVxAH4AC3h4dAAPY3VycmVudERhdGFiYXNldAAHdGhyZWFkeHg="/>
+ <listAttribute key="debugger.view.DisassemblyView:current">
+ <listEntry value="&lt;Next Instruction&gt;"/>
+ <listEntry value="100"/>
+ </listAttribute>
+ <listAttribute key="debugger.view.ExpressionsView">
+ <listEntry value="thread_0_counter"/>
+ <listEntry value="thread_1_counter"/>
+ <listEntry value="thread_1_messages_sent"/>
+ <listEntry value="thread_2_counter"/>
+ <listEntry value="thread_2_messages_received"/>
+ <listEntry value="thread_3_counter"/>
+ <listEntry value="thread_4_counter"/>
+ <listEntry value="thread_5_counter"/>
+ <listEntry value="thread_6_counter"/>
+ <listEntry value="thread_7_counter"/>
+ <listEntry value="_txm_module_manager_memory_fault_info"/>
+ </listAttribute>
+ <mapAttribute key="debugger.view.ExpressionsView.ExpressionsData">
+ <mapEntry key="0" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="1" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="10" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,88;NODE_TYPE,VALUE;FORMATTER,com.arm.debug.views.common.outline.DefaultDataFormatter"/>
+ <mapEntry key="2" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="3" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="4" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="5" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="8" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ <mapEntry key="9" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
+ </mapAttribute>
+ <stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;false&#9;355&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;127&#9;-1&#9;true&#9;2&#9;true&#9;false&#9;129&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;400&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;65&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;48&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;122&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;69&#9;-1&#9;true"/>
+ <stringAttribute key="debugger.view.MemoryView" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;page&gt;&#10;&#9;&lt;memoryView/&gt;&#10;&lt;/page&gt;&#10;"/>
+ <listAttribute key="debugger.view.MemoryView:current">
+ <listEntry value=""/>
+ <listEntry value=""/>
+ </listAttribute>
+ <stringAttribute key="debugger.view.NewRegisterView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;77&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;109&#9;-1&#9;true&#9;2&#9;true&#9;false&#9;222&#9;-1&#9;true&#9;3&#9;false&#9;true&#9;47&#9;-1&#9;true&#9;4&#9;false&#9;true&#9;56&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;37&#9;-1&#9;true&#9;6&#9;false&#9;true&#9;74&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;53&#9;-1&#9;true"/>
+ <stringAttribute key="debugger.view.NewRegisterView:_selectedRegisterSet" value="All registers"/>
+ <mapAttribute key="debugger.view.NewRegisterView_registerSets"/>
+ <stringAttribute key="debugger.view.StackView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;56&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;109&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;52&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;47&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;56&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;43&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;74&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;61&#9;-1&#9;true"/>
+ <listAttribute key="debugger.view.TraceView:TRACE_EXPORT_FILTERS"/>
+ <stringAttribute key="debugger.view.VariableTreeView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;178&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;109&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;118&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;47&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;56&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;43&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;74&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;61&#9;-1&#9;true"/>
+ <listAttribute key="debugger.view.VariableTreeView:USER_ADDED_FILE_STATICS"/>
+ <listAttribute key="debugger.view.VariableTreeView:USER_ADDED_GLOBALS"/>
+ <booleanAttribute key="debugger.view.expression.DrawAsHex" value="false"/>
+ <booleanAttribute key="debugger.view.register.DrawAsHex" value="false"/>
+ <stringAttribute key="debugger.view.symbols.FunctionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;60&#9;1&#9;true&#9;1&#9;false&#9;true&#9;123&#9;-1&#9;true&#9;2&#9;false&#9;true&#9;109&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;109&#9;0&#9;true&#9;4&#9;true&#9;true&#9;103&#9;-1&#9;true&#9;5&#9;false&#9;true&#9;47&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;134&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;62&#9;-1&#9;true"/>
+ <booleanAttribute key="debugger.view.variable.DrawAsHex" value="false"/>
+ <stringAttribute key="dtsl_config" value="DtslScript"/>
+ <stringAttribute key="dtsl_config_script" value="CDB://../../Arm FVP/VE_Cortex_R4/dtsl_config_script.py"/>
+ <stringAttribute key="dtsl_options_file" value="default"/>
+ <stringAttribute key="dtsl_tracecapture_option" value="options.trace.traceCapture"/>
+ <stringAttribute key="launch_configuration_version" value="5.29.2"/>
+ <booleanAttribute key="linuxOS" value="false"/>
+ <stringAttribute key="model_connection_address" value=""/>
+ <stringAttribute key="model_iris" value="1"/>
+ <stringAttribute key="model_params" value="-C daughterboard.core.NUM_MPU_REGION=12"/>
+ <booleanAttribute key="runAfterConnect" value="false"/>
+ <listAttribute key="setup">
+ <listEntry value="CDB://Scripts/rtsm_launcher.py"/>
+ <listEntry value="&quot;FVP_VE_Cortex-R4&quot;"/>
+ </listAttribute>
+ <stringAttribute key="stopAtExpression" value="main"/>
+ <stringAttribute key="watchpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;watchpoints&gt;&#10;&lt;/watchpoints&gt;&#10;"/>
+</launchConfiguration>