diff options
| author | Yuxin Zhou <[email protected]> | 2022-07-26 02:04:40 +0000 |
|---|---|---|
| committer | Yuxin Zhou <[email protected]> | 2022-07-26 02:04:40 +0000 |
| commit | 8c3c08f10826c4d5332a6d8e2fdf014b793a456a (patch) | |
| tree | c6c2528d7901b11ec5173bdd0bc38339ab18288f /ports_module | |
| parent | 54cda6ee9e68cd9701d759df13e3f6e41429b9bc (diff) | |
Release 6.1.12v6.1.12_rel
Diffstat (limited to 'ports_module')
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=""${workspace_loc:/tx/inc_port}""/> + + <listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic}""/> + + <listOptionValue builtIn="false" value=""${workspace_loc:/tx/inc_generic_modules}""/> + + </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=""${workspace_loc:/tx/Debug/tx.a}""/> + + </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)->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:&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)->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->tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers[0]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers->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->tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers[1]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->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->tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers[2]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->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->tx_thread_module_instance_ptr:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->txm_module_instance_mpu_registers[3]:VALUE:((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->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="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_resume.c" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_resume.c" line="590"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_resume.c" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_resume.c" line="590"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="176"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="176"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="159"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="159"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_restore.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_restore.S" line="151"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_restore.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_restore.S" line="151"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_save.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_save.S" line="133"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_thread_context_save.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_thread_context_save.S" line="133"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="401"/> 		<location index="0" enabled="true" version="2" debugFile="D:/threadx/modules/txm58/5.8.2/tx58_cortex-r4ac6/v51ds5/tx/tx_initialize_low_level.S" hostFile="D:\threadx\modules\txm58\5.8.2\tx58_cortex-r4ac6\v51ds5\tx\tx_initialize_low_level.S" line="401"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/tx/tx_initialize_low_level.S" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\tx\tx_initialize_low_level.S" line="401"/> 		<location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/tx/tx_initialize_low_level.S" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\tx\tx_initialize_low_level.S" line="401"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module_manager/sample_threadx_module_manager.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module_manager\sample_threadx_module_manager.c" line="94"/> 		<location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module_manager/sample_threadx_module_manager.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module_manager\sample_threadx_module_manager.c" line="94"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module/sample_threadx_module.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module\sample_threadx_module.c" line="107"/> 		<location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill_original/sample_threadx_module/sample_threadx_module.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill_original\sample_threadx_module\sample_threadx_module.c" line="107"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/tx/tx_initialize_low_level.S" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\tx\tx_initialize_low_level.S" line="401"/> 		<location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/tx/tx_initialize_low_level.S" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\tx\tx_initialize_low_level.S" line="401"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/sample_threadx_module/sample_threadx_module.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\sample_threadx_module\sample_threadx_module.c" line="274"/> 		<location index="0" enabled="true" version="2" debugFile="D:/Documents/work/modules_testing/txmcortex-r4_mpu_arm_RC1-frombill/sample_threadx_module/sample_threadx_module.c" hostFile="D:\Documents\work\modules_testing\txmcortex-r4_mpu_arm_RC1-frombill\sample_threadx_module\sample_threadx_module.c" line="274"/> 	</breakpoint> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" address="0x0001C46C" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_test/ports_module/cortex-r4/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_test\ports_module\cortex-r4\ac6\example_build\sample_threadx\sample_threadx.c" line="193" function="thread_0_entry"/> 		<location index="0" enabled="true" version="2" address="0x0001C46C" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_test/ports_module/cortex-r4/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_test\ports_module\cortex-r4\ac6\example_build\sample_threadx\sample_threadx.c" line="193" function="thread_0_entry"/> 	</breakpoint> </breakpoints> "/> + <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses"> + <listEntry value="<Next Instruction>"/> + <listEntry value=""/> + <listEntry value="&(((TXM_MODULE_INSTANCE *)_tx_thread_current_ptr->tx_thread_module_instance_ptr)->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="<Next Instruction>"/> + <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	8	0	true	false	355	-1	true	1	false	true	127	-1	true	2	true	false	129	-1	true	3	true	true	400	-1	true	4	true	true	65	-1	true	5	true	true	48	-1	true	6	true	true	122	-1	true	7	true	true	69	-1	true"/> + <stringAttribute key="debugger.view.MemoryView" value="<?xml version="1.0" encoding="UTF-8"?> <page> 	<memoryView/> </page> "/> + <listAttribute key="debugger.view.MemoryView:current"> + <listEntry value=""/> + <listEntry value=""/> + </listAttribute> + <stringAttribute key="debugger.view.NewRegisterView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	77	-1	true	1	false	true	109	-1	true	2	true	false	222	-1	true	3	false	true	47	-1	true	4	false	true	56	-1	true	5	true	true	37	-1	true	6	false	true	74	-1	true	7	true	true	53	-1	true"/> + <stringAttribute key="debugger.view.NewRegisterView:_selectedRegisterSet" value="All registers"/> + <mapAttribute key="debugger.view.NewRegisterView_registerSets"/> + <stringAttribute key="debugger.view.StackView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	56	-1	true	1	false	true	109	-1	true	2	true	true	52	-1	true	3	true	true	47	-1	true	4	true	true	56	-1	true	5	true	true	43	-1	true	6	true	true	74	-1	true	7	true	true	61	-1	true"/> + <listAttribute key="debugger.view.TraceView:TRACE_EXPORT_FILTERS"/> + <stringAttribute key="debugger.view.VariableTreeView:DebugOutlineColumnState" value="OutlineConfig1	8	0	true	true	178	-1	true	1	false	true	109	-1	true	2	true	true	118	-1	true	3	true	true	47	-1	true	4	true	true	56	-1	true	5	true	true	43	-1	true	6	true	true	74	-1	true	7	true	true	61	-1	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	8	0	true	true	60	1	true	1	false	true	123	-1	true	2	false	true	109	-1	true	3	true	true	109	0	true	4	true	true	103	-1	true	5	false	true	47	-1	true	6	true	true	134	-1	true	7	true	true	62	-1	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=""FVP_VE_Cortex-R4""/> + </listAttribute> + <stringAttribute key="stopAtExpression" value="main"/> + <stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/> +</launchConfiguration> |
