diff --git a/README.md b/README.md
index 083368bb..92f79ff9 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ $ git clone https://github.com/azure-rtos/threadx.git
## Building as a static library
-Each component of Azure RTOS comes with a composible CMake-based build system that supports many different MCUs and host systems. Integrating any of these components into your device app code is as simple as adding a git submodule and then including it in your build using the CMake command `add_subdirectory()`.
+Each component of Azure RTOS comes with a composable CMake-based build system that supports many different MCUs and host systems. Integrating any of these components into your device app code is as simple as adding a git submodule and then including it in your build using the CMake command `add_subdirectory()`.
While the typical usage pattern is to include threadx into your device code source tree to be built & linked with your code, you can compile this project as a standalone static library to confirm your build is set up correctly.
@@ -103,7 +103,7 @@ The following are references to additional Azure RTOS and Azure IoT in general:
| | |
|---|---|
| TraceX Installer | https://aka.ms/azrtos-tracex-installer |
-| Azure RTOS Documenation and Guides: | https://docs.microsoft.com/azure/rtos |
+| Azure RTOS Documentation and Guides: | https://docs.microsoft.com/azure/rtos |
| Azure RTOS Website: | https://azure.microsoft.com/services/rtos/ |
| Azure RTOS Sales Questions: | https://azure-rtos.ms-iot-contact.com/ |
| For technical questions check out Microsoft Q/A for Azure IoT: | https://aka.ms/QnA/azure-rtos |
diff --git a/common/inc/tx_api.h b/common/inc/tx_api.h
index 4b7dbc51..140e4cc2 100644
--- a/common/inc/tx_api.h
+++ b/common/inc/tx_api.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* tx_api.h PORTABLE C */
-/* 6.1.2 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -58,6 +58,9 @@
/* moved TX_THREAD_GET_SYSTEM_ */
/* STATE to tx_api.h, */
/* resulting in version 6.1.2 */
+/* 12-31-2020 William E. Lamie Modified comment(s), and */
+/* increased patch version, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
@@ -90,7 +93,7 @@ extern "C" {
#define AZURE_RTOS_THREADX
#define THREADX_MAJOR_VERSION 6
#define THREADX_MINOR_VERSION 1
-#define THREADX_PATCH_VERSION 2
+#define THREADX_PATCH_VERSION 3
/* Define the following symbol for backward compatibility */
#define EL_PRODUCT_THREADX
diff --git a/common_modules/inc/txm_module.h b/common_modules/inc/txm_module.h
index bac2c581..aa9d2f92 100644
--- a/common_modules/inc/txm_module.h
+++ b/common_modules/inc/txm_module.h
@@ -10,37 +10,40 @@
/**************************************************************************/
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Module Interface (API) */
-/** */
-/**************************************************************************/
-/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Module Interface (API) */
+/** */
+/**************************************************************************/
+/**************************************************************************/
-/**************************************************************************/
-/* */
-/* APPLICATION INTERFACE DEFINITION RELEASE */
-/* */
-/* txm_module.h PORTABLE C */
-/* 6.1 */
+/**************************************************************************/
+/* */
+/* APPLICATION INTERFACE DEFINITION RELEASE */
+/* */
+/* txm_module.h PORTABLE C */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
-/* DESCRIPTION */
-/* */
-/* This file defines the basic module constants, interface structures, */
-/* and function prototypes. */
-/* */
-/* RELEASE HISTORY */
-/* */
+/* DESCRIPTION */
+/* */
+/* This file defines the basic module constants, interface structures, */
+/* and function prototypes. */
+/* */
+/* RELEASE HISTORY */
+/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), added */
+/* port-specific extension, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
@@ -329,6 +332,8 @@ extern "C" {
#define TXM_MODULE_OBJECT_ALLOCATE_CALL 95
#define TXM_MODULE_OBJECT_DEALLOCATE_CALL 96
+#define TXM_MODULE_PORT_EXTENSION_API_ID_START 500
+#define TXM_MODULE_PORT_EXTENSION_API_ID_END 999
/* Determine the API call IDs for other components. */
@@ -508,7 +513,7 @@ typedef struct TXM_MODULE_ALLOCATED_OBJECT_STRUCT
*txm_module_allocated_object_next,
*txm_module_allocated_object_previous;
ULONG txm_module_object_size;
-} TXM_MODULE_ALLOCATED_OBJECT;
+} TXM_MODULE_ALLOCATED_OBJECT;
/* Determine if module code is being compiled. If so, remap the ThreadX API to
@@ -571,6 +576,7 @@ VOID _txm_module_usbx_duo_callback_request(TXM_MODULE_CALLBACK_MESSAGE *callbac
resident portion of the application. */
#define txm_module_manager_initialize _txm_module_manager_initialize
+#define txm_module_manager_absolute_load _txm_module_manager_absolute_load
#define txm_module_manager_in_place_load _txm_module_manager_in_place_load
#define txm_module_manager_file_load _txm_module_manager_file_load
#define txm_module_manager_memory_load _txm_module_manager_memory_load
@@ -607,6 +613,7 @@ UINT _txm_module_manager_application_request(ULONG request, ALIGN_TYPE param_1,
UINT _txm_module_manager_file_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, FX_MEDIA *media_ptr, CHAR *file_name);
#endif
UINT _txm_module_manager_initialize(VOID *module_memory_start, ULONG module_memory_size);
+UINT _txm_module_manager_absolute_load(TXM_MODULE_INSTANCE *module_instance, CHAR *name, VOID *module_location);
UINT _txm_module_manager_in_place_load(TXM_MODULE_INSTANCE *module_instance, CHAR *name, VOID *module_location);
UINT _txm_module_manager_internal_load(TXM_MODULE_INSTANCE *module_instance, CHAR *name, VOID *module_location,
ULONG code_size, VOID *code_allocation_ptr, ULONG code_allocation_size);
diff --git a/common_modules/module_manager/src/txm_module_manager_absolute_load.c b/common_modules/module_manager/src/txm_module_manager_absolute_load.c
new file mode 100644
index 00000000..f0868234
--- /dev/null
+++ b/common_modules/module_manager/src/txm_module_manager_absolute_load.c
@@ -0,0 +1,439 @@
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** Module Manager */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#define TX_SOURCE_CODE
+
+#include "tx_api.h"
+#include "tx_initialize.h"
+#include "tx_mutex.h"
+#include "tx_thread.h"
+#include "tx_byte_pool.h"
+#include "txm_module.h"
+#include "txm_module_manager_util.h"
+
+
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _txm_module_manager_absolute_load PORTABLE C */
+/* 6.1.3 */
+/* AUTHOR */
+/* */
+/* Andres Mlinar, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This function ensures the code-related and data-related parts of */
+/* the module preamble are valid and prepares the module for */
+/* execution. */
+/* */
+/* INPUT */
+/* */
+/* module_instance Module instance pointer */
+/* module_name Module name pointer */
+/* module_location Module code location */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _tx_byte_allocate Allocate data area */
+/* _tx_mutex_get Get protection mutex */
+/* _tx_mutex_put Release protection mutex */
+/* */
+/* CALLED BY */
+/* */
+/* Application code */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Andres Mlinar Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+UINT _txm_module_manager_absolute_load(TXM_MODULE_INSTANCE *module_instance, CHAR *module_name, VOID *module_location)
+{
+
+TX_INTERRUPT_SAVE_AREA
+
+TXM_MODULE_PREAMBLE *module_preamble;
+ULONG code_size;
+ULONG code_alignment;
+ULONG code_allocation_size_ignored;
+UINT status;
+
+TXM_MODULE_INSTANCE *next_module, *previous_module;
+ULONG start_stop_stack_size;
+ULONG callback_stack_size;
+ULONG code_size_ignored;
+ULONG code_alignment_ignored;
+ALIGN_TYPE data_start;
+ULONG data_size;
+ULONG data_alignment;
+ULONG data_allocation_size;
+ULONG module_properties;
+CHAR *memory_ptr;
+
+
+ /* Check for interrupt call. */
+ if (TX_THREAD_GET_SYSTEM_STATE() != 0)
+ {
+
+ /* Now, make sure the call is from an interrupt and not initialization. */
+ if (TX_THREAD_GET_SYSTEM_STATE() < TX_INITIALIZE_IN_PROGRESS)
+ {
+
+ /* Invalid caller of this function, return appropriate error code. */
+ return(TX_CALLER_ERROR);
+ }
+ }
+
+ /* Determine if the module manager has not been initialized yet. */
+ if (_txm_module_manager_ready != TX_TRUE)
+ {
+
+ /* Module manager has not been initialized. */
+ return(TX_NOT_AVAILABLE);
+ }
+
+ /* Determine if the module is valid. */
+ if (module_instance == TX_NULL)
+ {
+
+ /* Invalid module pointer. */
+ return(TX_PTR_ERROR);
+ }
+
+ /* Get module manager protection mutex. */
+ _tx_mutex_get(&_txm_module_manager_mutex, TX_WAIT_FOREVER);
+
+ /* Determine if the module is already valid. */
+ if (module_instance -> txm_module_instance_id == TXM_MODULE_ID)
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Module already loaded. */
+ return(TXM_MODULE_ALREADY_LOADED);
+ }
+
+ /* Pickup the module's information. */
+ module_preamble = (TXM_MODULE_PREAMBLE *) module_location;
+
+ /* Check to make sure there is a valid module to load. */
+ if (module_preamble -> txm_module_preamble_id != TXM_MODULE_ID)
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Invalid module preamble. */
+ return(TXM_MODULE_INVALID);
+ }
+
+ /* Check the properties of this module. */
+ module_properties = module_preamble -> txm_module_preamble_property_flags & TXM_MODULE_OPTIONS_MASK;
+ if (/* Ensure the requested properties are supported. */
+ ((module_properties & _txm_module_manager_properties_supported) != module_properties) ||
+ /* Ensure the required properties are there. */
+ ((_txm_module_manager_properties_required & module_properties) != _txm_module_manager_properties_required) ||
+ /* If memory protection is enabled, then so must user mode. */
+ ((module_properties & TXM_MODULE_MEMORY_PROTECTION) && !(module_properties & TXM_MODULE_USER_MODE))
+ )
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Invalid properties. Return error. */
+ return(TXM_MODULE_INVALID_PROPERTIES);
+ }
+
+ /* Check for valid module entry offsets. */
+ if ((module_preamble -> txm_module_preamble_shell_entry_function == 0) ||
+ (module_preamble -> txm_module_preamble_start_function == 0))
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Invalid module preamble. */
+ return(TXM_MODULE_INVALID);
+ }
+
+ /* Check for valid sizes. */
+ if ((module_preamble -> txm_module_preamble_code_size == 0) ||
+ /* (module_preamble -> txm_module_preamble_data_size == 0) || *** a zero data size is valid */
+ (module_preamble -> txm_module_preamble_start_stop_stack_size == 0) ||
+ (module_preamble -> txm_module_preamble_callback_stack_size == 0))
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Invalid module preamble. */
+ return(TXM_MODULE_INVALID);
+ }
+
+ /* Get the amount of the bytes we need to allocate for the module's code
+ as well as the required alignment. Note that because this is an absolute
+ load, we only want the code alignment so we can check it. */
+ status = _txm_module_manager_util_code_allocation_size_and_alignment_get(module_preamble, &code_alignment, &code_allocation_size_ignored);
+ if (status != TX_SUCCESS)
+ {
+
+ /* Math overflow error occurred. */
+ return(status);
+ }
+
+ /* Since this is an absolute load, check the alignment of the module's instruction area (code). */
+ TXM_MODULE_MANAGER_CHECK_CODE_ALIGNMENT(module_location, code_alignment)
+
+ /* Initialize module control block to all zeros. */
+ TX_MEMSET(module_instance, 0, sizeof(TXM_MODULE_INSTANCE));
+
+ /* Pickup the basic module sizes. */
+ code_size = module_preamble -> txm_module_preamble_code_size;
+ data_size = module_preamble -> txm_module_preamble_data_size;
+ start_stop_stack_size = module_preamble -> txm_module_preamble_start_stop_stack_size;
+ callback_stack_size = module_preamble -> txm_module_preamble_callback_stack_size;
+
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_size, TXM_MODULE_DATA_ALIGNMENT, data_size);
+ data_size = ((data_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
+
+ /* Adjust the size of the module elements to be aligned to the default alignment. We do this
+ so that when we partition the allocated memory, we can simply place these regions right beside
+ each other without having to align their pointers. Note this only works when they all have
+ the same alignment. */
+
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(start_stop_stack_size, TXM_MODULE_DATA_ALIGNMENT, start_stop_stack_size);
+ start_stop_stack_size = ((start_stop_stack_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
+
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(callback_stack_size, TXM_MODULE_DATA_ALIGNMENT, callback_stack_size);
+ callback_stack_size = ((callback_stack_size - 1)/TXM_MODULE_DATA_ALIGNMENT) * TXM_MODULE_DATA_ALIGNMENT;
+
+ /* Update the data size to account for the default thread stacks. */
+ data_allocation_size = 0;
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_allocation_size, start_stop_stack_size, data_allocation_size);
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_allocation_size, callback_stack_size, data_allocation_size);
+
+ /* Setup the default code and data alignments. */
+ data_alignment = (ULONG) TXM_MODULE_DATA_ALIGNMENT;
+
+ /* Get the port-specific alignment for the data size. Note we only want data
+ so we pass values of 1 for code (to avoid any possible div by 0 errors). */
+ code_size_ignored = 1;
+ code_alignment_ignored = 1;
+ TXM_MODULE_MANAGER_ALIGNMENT_ADJUST(module_preamble, code_size_ignored, code_alignment_ignored, data_allocation_size, data_alignment)
+
+ /* Calculate the module's total RAM memory requirement. This entire area is allocated from the module
+ manager's byte pool. The general layout is defined as follows:
+
+ Lowest Address: Start of start/stop thread stack
+ ... [note: thread entry info is embedded near end of stack areas]
+ End of start/stop thread stack
+
+ Start of callback thread stack
+ ... [note: thread entry info is embedded near end of stack areas]
+ End of callback thread stack
+
+ Highest Address: */
+
+ /* Add an extra alignment increment so we can align the pointer after allocation. */
+ TXM_MODULE_MANAGER_UTIL_MATH_ADD_ULONG(data_allocation_size, data_alignment, data_allocation_size);
+
+ /* Allocate memory for the module. */
+ status = _tx_byte_allocate(&_txm_module_manager_byte_pool, (VOID **) &memory_ptr, data_allocation_size, TX_NO_WAIT);
+
+ /* Determine if the module memory allocation was successful. */
+ if (status)
+ {
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* No memory, return an error. */
+ return(TX_NO_MEMORY);
+ }
+
+ /* Clear the allocated memory. */
+ TX_MEMSET(memory_ptr, ((UCHAR) 0), data_allocation_size);
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Setup the module instance structure. */
+ module_instance -> txm_module_instance_id = TXM_MODULE_ID;
+
+ /* Save the module name. */
+ module_instance -> txm_module_instance_name = module_name;
+
+ /* Save the module properties. */
+ module_instance -> txm_module_instance_property_flags = module_preamble -> txm_module_preamble_property_flags;
+
+ /* Set the module data memory allocation. This is the address released
+ when the module is unloaded. */
+ module_instance -> txm_module_instance_data_allocation_ptr = (VOID *) memory_ptr;
+
+ /* Save the data allocation size. */
+ module_instance -> txm_module_instance_data_allocation_size = data_allocation_size;
+
+ /* Calculate the actual start of the data area. This needs to be adjusted based on the alignment. */
+ data_start = (ALIGN_TYPE) memory_ptr;
+ data_start = (data_start + (((ALIGN_TYPE)data_alignment) - 1)) & ~(((ALIGN_TYPE)data_alignment) - 1);
+ memory_ptr = (CHAR *) data_start;
+
+ /* Compute the beginning and end of the data area. */
+#ifdef ALIGN_TYPE_DEFINED
+ module_instance -> txm_module_instance_data_start = (VOID *) (((CHAR *) (ALIGN_TYPE) module_preamble->txm_module_preamble_code_size) + sizeof(TXM_MODULE_PREAMBLE));
+ module_instance -> txm_module_instance_data_end = (VOID *) (((CHAR *) (ALIGN_TYPE) module_instance -> txm_module_instance_data_start) + module_preamble->txm_module_preamble_data_size);
+#else
+ module_instance -> txm_module_instance_data_start = (VOID *) (((CHAR *) module_preamble->txm_module_preamble_code_size) + sizeof(TXM_MODULE_PREAMBLE));
+ module_instance -> txm_module_instance_data_end = (VOID *) (((CHAR *) module_instance -> txm_module_instance_data_start) + module_preamble->txm_module_preamble_data_size);
+#endif
+
+ /* Save the size of the data area. */
+ module_instance -> txm_module_instance_data_size = data_size;
+
+ /* Set the module code memory allocation. This is the address released
+ when the module is unloaded. */
+ module_instance -> txm_module_instance_code_allocation_ptr = (VOID *) NULL;
+
+ /* Save the code allocation size. */
+ module_instance -> txm_module_instance_code_allocation_size = 0;
+
+ /* Setup the code pointers. Since the code was loaded in-place, this is effectively just the values supplied in the API call. */
+ module_instance -> txm_module_instance_code_start = (VOID *) module_location;
+ module_instance -> txm_module_instance_code_end = (VOID *) (((CHAR *) module_location) + (code_size - 1));
+
+ /* Setup the code size. */
+ module_instance -> txm_module_instance_code_size = code_size;
+
+ /* Save the module's total memory usage. */
+ module_instance -> txm_module_instance_total_ram_usage = 0 /* Code is executed in place */ + data_allocation_size /* just the size of stacks */;
+
+ /* Set the module state to started. */
+ module_instance -> txm_module_instance_state = TXM_MODULE_LOADED;
+
+ /* Save the preamble pointer. */
+ module_instance -> txm_module_instance_preamble_ptr = module_preamble;
+
+ /* Save the module application ID in the module instance. */
+ module_instance -> txm_module_instance_application_module_id = module_preamble -> txm_module_preamble_application_module_id;
+
+ /* Setup the module's start/stop thread stack area. */
+ module_instance -> txm_module_instance_start_stop_stack_start_address = (VOID *) (memory_ptr);
+ module_instance -> txm_module_instance_start_stop_stack_size = start_stop_stack_size;
+ module_instance -> txm_module_instance_start_stop_stack_end_address = (VOID *) (memory_ptr + (start_stop_stack_size - 1));
+
+ /* Move the memory pointer forward. */
+ memory_ptr = memory_ptr + start_stop_stack_size;
+
+ /* Save the start/stop thread priority. */
+ module_instance -> txm_module_instance_start_stop_priority = module_preamble -> txm_module_preamble_start_stop_priority;
+
+ /* Setup the module's callback thread stack area. */
+ module_instance -> txm_module_instance_callback_stack_start_address = (VOID *) (memory_ptr);
+ module_instance -> txm_module_instance_callback_stack_size = callback_stack_size;
+ module_instance -> txm_module_instance_callback_stack_end_address = (VOID *) (memory_ptr + (callback_stack_size - 1));
+
+ /* Move the memory pointer forward. */
+ memory_ptr = memory_ptr + callback_stack_size;
+
+ /* Save the callback thread priority. */
+ module_instance -> txm_module_instance_callback_priority = module_preamble -> txm_module_preamble_callback_priority;
+
+ /* Setup the start of the module data section. */
+ module_instance -> txm_module_instance_module_data_base_address = (VOID *) (memory_ptr);
+
+ /* Build actual addresses based on load... Setup all the function pointers. Any adjustments needed to shell entry, start function, and callback function are defined in the
+ module preamble. */
+#ifdef ALIGN_TYPE_DEFINED
+ module_instance -> txm_module_instance_shell_entry_function = (VOID (*)(TX_THREAD *, TXM_MODULE_INSTANCE *)) ((VOID *) (ALIGN_TYPE) module_preamble -> txm_module_preamble_shell_entry_function);
+ module_instance -> txm_module_instance_start_thread_entry = (VOID (*)(ULONG)) ((VOID *) (ALIGN_TYPE) module_preamble -> txm_module_preamble_start_function);
+ module_instance -> txm_module_instance_callback_request_thread_entry = (VOID (*)(ULONG)) ((VOID *) (ALIGN_TYPE) module_preamble -> txm_module_preamble_callback_function);
+#else
+ module_instance -> txm_module_instance_shell_entry_function = (VOID (*)(TX_THREAD *, TXM_MODULE_INSTANCE *)) ((VOID *) module_preamble -> txm_module_preamble_shell_entry_function);
+ module_instance -> txm_module_instance_start_thread_entry = (VOID (*)(ULONG)) ((VOID *) module_preamble -> txm_module_preamble_start_function);
+ module_instance -> txm_module_instance_callback_request_thread_entry = (VOID (*)(ULONG)) ((VOID *) module_preamble -> txm_module_preamble_callback_function);
+#endif
+
+ /* Determine if there is a stop function for this module. */
+ if (module_preamble -> txm_module_preamble_stop_function)
+ {
+
+ /* Yes, there is a stop function, build the address. */
+#ifdef ALIGN_TYPE_DEFINED
+ module_instance -> txm_module_instance_stop_thread_entry = (VOID (*)(ULONG)) ((VOID *) (ALIGN_TYPE) module_preamble -> txm_module_preamble_stop_function);
+#else
+ module_instance -> txm_module_instance_stop_thread_entry = (VOID (*)(ULONG)) ((VOID *) module_preamble -> txm_module_preamble_stop_function);
+#endif
+ }
+ else
+ {
+
+ /* No, there is no stop function. Just set the pointer to NULL. */
+ module_instance -> txm_module_instance_stop_thread_entry = TX_NULL;
+ }
+
+ /* Load the module control block with port-specific information. */
+ TXM_MODULE_MANAGER_MODULE_SETUP(module_instance);
+
+ /* Now add the module to the linked list of created modules. */
+ if (_txm_module_manger_loaded_count++ == 0)
+ {
+
+ /* The loaded module list is empty. Add module to empty list. */
+ _txm_module_manager_loaded_list_ptr = module_instance;
+ module_instance -> txm_module_instance_loaded_next = module_instance;
+ module_instance -> txm_module_instance_loaded_previous = module_instance;
+ }
+ else
+ {
+
+ /* This list is not NULL, add to the end of the list. */
+ next_module = _txm_module_manager_loaded_list_ptr;
+ previous_module = next_module -> txm_module_instance_loaded_previous;
+
+ /* Place the new module in the list. */
+ next_module -> txm_module_instance_loaded_previous = module_instance;
+ previous_module -> txm_module_instance_loaded_next = module_instance;
+
+ /* Setup this module's created links. */
+ module_instance -> txm_module_instance_loaded_previous = previous_module;
+ module_instance -> txm_module_instance_loaded_next = next_module;
+ }
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Release the protection mutex. */
+ _tx_mutex_put(&_txm_module_manager_mutex);
+
+ /* Return success. */
+ return(TX_SUCCESS);
+}
diff --git a/common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c b/common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c
index 63c1acc5..355de996 100644
--- a/common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c
+++ b/common_modules/module_manager/src/txm_module_manager_kernel_dispatch.c
@@ -12,8 +12,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** ThreadX Component */
+/** */
+/** ThreadX Component */
/** */
/** Module Manager */
/** */
@@ -36,50 +36,53 @@
#include "txm_module_manager_util.h"
#include "txm_module_manager_dispatch.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _txm_module_kernel_dispatch PORTABLE C */
-/* 6.1 */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _txm_module_manager_kernel_dispatch PORTABLE C */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
-/* DESCRIPTION */
-/* */
-/* This function dispatches the module's kernel request based upon the */
-/* ID and parameters specified in the request. */
-/* */
-/* INPUT */
-/* */
-/* kernel_request Module's kernel request */
-/* param_1 First parameter */
-/* param_2 Second parameter */
-/* param_3 Third parameter */
-/* */
-/* OUTPUT */
-/* */
-/* status Completion status */
-/* */
-/* CALLS */
-/* */
-/* _txm_module_manager_application_request Application-specific req */
-/* _txm_module_manager_object_pointer_get Find object pointer */
-/* _txm_module_manager_thread_create Module thread create */
-/* [_txm_module_manager_*_dispatch] Optional external */
-/* component dispatch */
-/* ThreadX API Calls */
-/* */
-/* CALLED BY */
-/* */
-/* Application code */
-/* */
-/* RELEASE HISTORY */
-/* */
+/* DESCRIPTION */
+/* */
+/* This function dispatches the module's kernel request based upon the */
+/* ID and parameters specified in the request. */
+/* */
+/* INPUT */
+/* */
+/* kernel_request Module's kernel request */
+/* param_1 First parameter */
+/* param_2 Second parameter */
+/* param_3 Third parameter */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _txm_module_manager_application_request Application-specific req */
+/* _txm_module_manager_object_pointer_get Find object pointer */
+/* _txm_module_manager_thread_create Module thread create */
+/* [_txm_module_manager_*_dispatch] Optional external */
+/* component dispatch */
+/* ThreadX API Calls */
+/* */
+/* CALLED BY */
+/* */
+/* Application code */
+/* */
+/* RELEASE HISTORY */
+/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), added */
+/* port-specific dispatch, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
ALIGN_TYPE _txm_module_manager_kernel_dispatch(ULONG kernel_request, ALIGN_TYPE param_0, ALIGN_TYPE param_1, ALIGN_TYPE param_2)
@@ -679,6 +682,15 @@ TXM_MODULE_INSTANCE *module_instance;
default:
{
+#ifdef TXM_MODULE_PORT_DISPATCH
+ /* Is this a port-specific request? */
+ if ((kernel_request >= TXM_MODULE_PORT_EXTENSION_API_ID_START) && (kernel_request <= TXM_MODULE_PORT_EXTENSION_API_ID_END))
+ {
+ /* Yes, call the port-specific dispatcher. */
+ return_value = (ALIGN_TYPE) _txm_module_manager_port_dispatch(module_instance, kernel_request, param_0, param_1, param_2);
+ }
+#endif
+
/* Determine if an application request is present. */
if (kernel_request >= TXM_APPLICATION_REQUEST_ID_BASE)
{
diff --git a/common_modules/module_manager/src/txm_module_manager_start.c b/common_modules/module_manager/src/txm_module_manager_start.c
index e793e8ef..365803b5 100644
--- a/common_modules/module_manager/src/txm_module_manager_start.c
+++ b/common_modules/module_manager/src/txm_module_manager_start.c
@@ -10,15 +10,15 @@
/**************************************************************************/
-/**************************************************************************/
-/**************************************************************************/
-/** */
-/** ThreadX Component */
-/** */
-/** Module Manager */
-/** */
-/**************************************************************************/
-/**************************************************************************/
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Module Manager */
+/** */
+/**************************************************************************/
+/**************************************************************************/
#define TX_SOURCE_CODE
@@ -29,47 +29,48 @@
#include "txm_module.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _txm_module_manager_start PORTABLE C */
-/* 6.1 */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _txm_module_manager_start PORTABLE C */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
/* */
-/* DESCRIPTION */
-/* */
-/* This function starts execution of the specified module. */
-/* */
-/* INPUT */
-/* */
-/* module_instance Module instance pointer */
-/* */
-/* OUTPUT */
-/* */
-/* status Completion status */
-/* */
-/* CALLS */
-/* */
-/* _txm_module_manager_name_build Build module:thread name */
-/* _txm_module_manager_thread_create Module thread create */
-/* _tx_mutex_get Get protection mutex */
-/* _tx_mutex_put Release protection mutex */
-/* _tx_queue_create Create module callback queue */
-/* _tx_queue_delete Delete module callback queue */
-/* _tx_thread_resume Resume start thread */
-/* */
-/* CALLED BY */
-/* */
-/* Application code */
-/* */
-/* RELEASE HISTORY */
-/* */
+/* DESCRIPTION */
+/* */
+/* This function starts execution of the specified module. */
+/* */
+/* INPUT */
+/* */
+/* module_instance Module instance pointer */
+/* */
+/* OUTPUT */
+/* */
+/* status Completion status */
+/* */
+/* CALLS */
+/* */
+/* _txm_module_manager_thread_create Module thread create */
+/* _tx_mutex_get Get protection mutex */
+/* _tx_mutex_put Release protection mutex */
+/* _tx_queue_create Create module callback queue */
+/* _tx_queue_delete Delete module callback queue */
+/* _tx_thread_resume Resume start thread */
+/* */
+/* CALLED BY */
+/* */
+/* Application code */
+/* */
+/* RELEASE HISTORY */
+/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
UINT _txm_module_manager_start(TXM_MODULE_INSTANCE *module_instance)
diff --git a/common_modules/module_manager/src/txm_module_manager_thread_create.c b/common_modules/module_manager/src/txm_module_manager_thread_create.c
index 9a36d25d..58c8211e 100644
--- a/common_modules/module_manager/src/txm_module_manager_thread_create.c
+++ b/common_modules/module_manager/src/txm_module_manager_thread_create.c
@@ -21,11 +21,15 @@
/**************************************************************************/
#define TX_SOURCE_CODE
+#define TX_THREAD_SMP_SOURCE_CODE
+
+
+/* Include necessary system files. */
#include "tx_api.h"
#include "tx_trace.h"
-#include "tx_initialize.h"
#include "tx_thread.h"
+#include "tx_initialize.h"
#include "tx_timer.h"
#include "txm_module.h"
@@ -35,7 +39,7 @@
/* FUNCTION RELEASE */
/* */
/* _txm_module_manager_thread_create PORTABLE C */
-/* 6.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -47,22 +51,22 @@
/* */
/* INPUT */
/* */
-/* thread_ptr Thread control block pointer */
-/* name Pointer to thread name string */
-/* shell_function Shell function of the thread */
-/* entry_function Entry function of the thread */
-/* entry_input 32-bit input value to thread */
-/* stack_start Pointer to start of stack */
-/* stack_size Stack size in bytes */
-/* priority Priority of thread */
-/* (default 0-31) */
-/* preempt_threshold Preemption threshold */
-/* time_slice Thread time-slice value */
-/* auto_start Automatic start selection */
+/* thread_ptr Thread control block pointer */
+/* name Pointer to thread name string */
+/* shell_function Shell function of the thread */
+/* entry_function Entry function of the thread */
+/* entry_input 32-bit input value to thread */
+/* stack_start Pointer to start of stack */
+/* stack_size Stack size in bytes */
+/* priority Priority of thread */
+/* (default 0-31) */
+/* preempt_threshold Preemption threshold */
+/* time_slice Thread time-slice value */
+/* auto_start Automatic start selection */
/* */
/* OUTPUT */
/* */
-/* status Completion status */
+/* return status Thread create return status */
/* */
/* CALLS */
/* */
@@ -81,35 +85,41 @@
/* */
/* DATE NAME DESCRIPTION */
/* */
-/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), */
+/* fix stack overlap checking, */
+/* added 64-bit support, */
+/* added SMP support, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
-UINT _txm_module_manager_thread_create(TX_THREAD *thread_ptr, CHAR *name, VOID (*shell_function)(TX_THREAD *, TXM_MODULE_INSTANCE *),
- VOID (*entry_function)(ULONG), ULONG entry_input,
- VOID *stack_start, ULONG stack_size, UINT priority, UINT preempt_threshold,
- ULONG time_slice, UINT auto_start, UINT thread_control_block_size, TXM_MODULE_INSTANCE *module_instance)
+UINT _txm_module_manager_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr,
+ VOID (*shell_function)(TX_THREAD *, TXM_MODULE_INSTANCE *),
+ VOID (*entry_function)(ULONG id), ULONG entry_input,
+ VOID *stack_start, ULONG stack_size, UINT priority, UINT preempt_threshold,
+ ULONG time_slice, UINT auto_start,
+ UINT thread_control_block_size, TXM_MODULE_INSTANCE *module_instance)
{
TX_INTERRUPT_SAVE_AREA
-TX_THREAD *next_thread;
-TX_THREAD *previous_thread;
+#ifdef TX_THREAD_SMP
+UINT core_index;
+#endif
+TX_THREAD *next_thread;
+TX_THREAD *previous_thread;
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
-TX_THREAD *saved_thread_ptr;
-UINT saved_threshold = 0;
+TX_THREAD *saved_thread_ptr;
+UINT saved_threshold = ((UINT) 0);
#endif
+UCHAR *temp_ptr;
#ifdef TX_ENABLE_STACK_CHECKING
-ULONG new_stack_start;
-#endif
-TXM_MODULE_THREAD_ENTRY_INFO *thread_entry_info;
-VOID *stack_end;
-ULONG i;
-#ifndef TX_TIMER_PROCESS_IN_ISR
-TX_THREAD *current_thread;
-#endif
-#if TXM_MODULE_MEMORY_PROTECTION
-ULONG status;
+ALIGN_TYPE new_stack_start;
+ALIGN_TYPE updated_stack_start;
#endif
+TXM_MODULE_THREAD_ENTRY_INFO *thread_entry_info;
+VOID *stack_end;
+ULONG i;
/* First, check for an invalid thread pointer. */
if (thread_ptr == TX_NULL)
@@ -150,37 +160,12 @@ ULONG status;
}
/* Check the stack pointer to see if it overlaps with this thread's stack. */
-
- /*lint -e{946} suppress pointer comparison, since this is necessary. */
- if (((UCHAR *) ((VOID *) stack_start)) >= ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_start)))
+ if ((((UCHAR *) ((VOID *) stack_start)) <= ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_end))) &&
+ (((UCHAR *) ((VOID *) stack_end)) >= ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_start))))
{
-
- /*lint -e{946} suppress pointer comparison, since this is necessary. */
- if (((UCHAR *) ((VOID *) stack_start)) < ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_end)))
- {
-
- /* This stack overlaps with an existing thread, clear the stack pointer to
- force a stack error below. */
- stack_start = TX_NULL;
- break;
- }
- }
-
- /* Check the end of the stack to see if it is inside this thread's stack area as well. */
-
- /*lint -e{946} suppress pointer comparison, since this is necessary. */
- if (((UCHAR *) ((VOID *) stack_end)) >= ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_start)))
- {
-
- /*lint -e{946} suppress pointer comparison, since this is necessary. */
- if (((UCHAR *) ((VOID *) stack_end)) < ((UCHAR *) ((VOID *) next_thread -> tx_thread_stack_end)))
- {
-
- /* This stack overlaps with an existing thread, clear the stack pointer to
- force a stack error below. */
- stack_start = TX_NULL;
- break;
- }
+ /* Stacks overlap, clear the stack pointer to force a stack error below. */
+ stack_start = TX_NULL;
+ break;
}
/* Move to the next thread. */
@@ -256,16 +241,19 @@ ULONG status;
}
#ifndef TX_TIMER_PROCESS_IN_ISR
-
- /* Pickup thread pointer. */
- TX_THREAD_GET_CURRENT(current_thread)
-
- /* Check for invalid caller of this function. First check for a calling thread. */
- if (current_thread == &_tx_timer_thread)
{
+ TX_THREAD *current_thread;
- /* Invalid caller of this function, return appropriate error code. */
- return(TX_CALLER_ERROR);
+ /* Pickup thread pointer. */
+ TX_THREAD_GET_CURRENT(current_thread)
+
+ /* Check for invalid caller of this function. First check for a calling thread. */
+ if (current_thread == &_tx_timer_thread)
+ {
+
+ /* Invalid caller of this function, return appropriate error code. */
+ return(TX_CALLER_ERROR);
+ }
}
#endif
@@ -295,21 +283,22 @@ ULONG status;
/* Ensure that there are two ULONG of 0xEF patterns at the top and
bottom of the thread's stack. This will be used to check for stack
overflow conditions during run-time. */
- stack_size = ((stack_size/sizeof(ULONG)) * sizeof(ULONG)) - sizeof(ULONG);
+ stack_size = ((stack_size/(sizeof(ULONG))) * (sizeof(ULONG))) - (sizeof(ULONG));
/* Ensure the starting stack address is evenly aligned. */
- new_stack_start = ((((ULONG) stack_start) + (sizeof(ULONG) - 1) ) & (~(sizeof(ULONG) - 1)));
+ new_stack_start = TX_POINTER_TO_ALIGN_TYPE_CONVERT(stack_start);
+ updated_stack_start = ((((ULONG) new_stack_start) + ((sizeof(ULONG)) - ((ULONG) 1)) ) & (~((sizeof(ULONG)) - ((ULONG) 1))));
/* Determine if the starting stack address is different. */
- if (new_stack_start != ((ULONG) stack_start))
+ if (new_stack_start != updated_stack_start)
{
/* Yes, subtract another ULONG from the size to avoid going past the stack area. */
- stack_size = stack_size - sizeof(ULONG);
+ stack_size = stack_size - (sizeof(ULONG));
}
/* Update the starting stack pointer. */
- stack_start = (VOID *) new_stack_start;
+ stack_start = TX_ALIGN_TYPE_TO_POINTER_CONVERT(updated_stack_start);
#endif
/* Allocate the thread entry information at the top of thread's stack - Leaving one
@@ -321,53 +310,81 @@ ULONG status;
/* Initialize thread control block to all zeros. */
TX_MEMSET(thread_ptr, 0, sizeof(TX_THREAD));
-
+
#if TXM_MODULE_MEMORY_PROTECTION
/* If this is a memory protected module, allocate a kernel stack. */
if((module_instance -> txm_module_instance_property_flags) & TXM_MODULE_MEMORY_PROTECTION)
{
+ ULONG status;
+
/* Allocate kernel stack space. */
status = _txm_module_manager_object_allocate((VOID **) &(thread_ptr -> tx_thread_module_kernel_stack_start), TXM_MODULE_KERNEL_STACK_SIZE, module_instance);
if(status)
{
return(status);
}
-
+
#ifndef TX_DISABLE_STACK_FILLING
/* Set the thread stack to a pattern prior to creating the initial
stack frame. This pattern is used by the stack checking routines
to see how much has been used. */
TX_MEMSET(thread_ptr -> tx_thread_module_kernel_stack_start, ((UCHAR) TX_STACK_FILL), TXM_MODULE_KERNEL_STACK_SIZE);
#endif
-
+
/* Align kernel stack pointer. */
thread_ptr -> tx_thread_module_kernel_stack_end = (VOID *) (((ALIGN_TYPE)(thread_ptr -> tx_thread_module_kernel_stack_start) + TXM_MODULE_KERNEL_STACK_SIZE) & ~0x07);
/* Set kernel stack size. */
thread_ptr -> tx_thread_module_kernel_stack_size = TXM_MODULE_KERNEL_STACK_SIZE;
}
-
+
/* Place the stack parameters into the thread's control block. */
- thread_ptr -> tx_thread_module_stack_start = stack_start;
- thread_ptr -> tx_thread_module_stack_size = stack_size;
+ thread_ptr -> tx_thread_module_stack_start = stack_start;
+ thread_ptr -> tx_thread_module_stack_size = stack_size;
#endif
/* Place the supplied parameters into the thread's control block. */
- thread_ptr -> tx_thread_name = name;
- thread_ptr -> tx_thread_entry = entry_function;
- thread_ptr -> tx_thread_entry_parameter = entry_input;
- thread_ptr -> tx_thread_stack_start = stack_start;
- thread_ptr -> tx_thread_stack_size = stack_size;
- thread_ptr -> tx_thread_stack_end = (VOID *) (((UCHAR *) stack_start) + (stack_size-1));
+ thread_ptr -> tx_thread_name = name_ptr;
+ thread_ptr -> tx_thread_entry = entry_function;
+ thread_ptr -> tx_thread_entry_parameter = entry_input;
+ thread_ptr -> tx_thread_stack_start = stack_start;
+ thread_ptr -> tx_thread_stack_size = stack_size;
+ thread_ptr -> tx_thread_priority = priority;
+ thread_ptr -> tx_thread_user_priority = priority;
+ thread_ptr -> tx_thread_time_slice = time_slice;
+ thread_ptr -> tx_thread_new_time_slice = time_slice;
+ thread_ptr -> tx_thread_inherit_priority = ((UINT) TX_MAX_PRIORITIES);
+#ifdef TX_THREAD_SMP
+ thread_ptr -> tx_thread_smp_core_executing = ((UINT) TX_THREAD_SMP_MAX_CORES);
+ thread_ptr -> tx_thread_smp_cores_excluded = ((ULONG) 0);
+#ifndef TX_THREAD_SMP_DYNAMIC_CORE_MAX
+ thread_ptr -> tx_thread_smp_cores_allowed = ((ULONG) TX_THREAD_SMP_CORE_MASK);
+#else
+ thread_ptr -> tx_thread_smp_cores_allowed = (((ULONG) 1) << _tx_thread_smp_max_cores) - 1;
+#endif
+
+#ifdef TX_THREAD_SMP_ONLY_CORE_0_DEFAULT
+
+ /* Default thread creation such that core0 is the only allowed core for execution, i.e., bit 1 is set to exclude core1. */
+ thread_ptr -> tx_thread_smp_cores_excluded = (TX_THREAD_SMP_CORE_MASK & 0xFFFFFFFE);
+ thread_ptr -> tx_thread_smp_cores_allowed = 1;
+
+ /* Default the timers to run on core 0 as well. */
+ thread_ptr -> tx_thread_timer.tx_timer_internal_smp_cores_excluded = (TX_THREAD_SMP_CORE_MASK & 0xFFFFFFFE);
+
+ /* Default the mapped to 0 too. */
+ thread_ptr -> tx_thread_smp_core_mapped = 0;
+#endif
+#endif
+
+ /* Calculate the end of the thread's stack area. */
+ temp_ptr = TX_VOID_TO_UCHAR_POINTER_CONVERT(stack_start);
+ temp_ptr = (TX_UCHAR_POINTER_ADD(temp_ptr, (stack_size - ((ULONG) 1))));
+ thread_ptr -> tx_thread_stack_end = TX_UCHAR_TO_VOID_POINTER_CONVERT(temp_ptr);
#if TXM_MODULE_MEMORY_PROTECTION
thread_ptr -> tx_thread_module_stack_end = thread_ptr -> tx_thread_stack_end;
-#endif
- thread_ptr -> tx_thread_priority = priority;
- thread_ptr -> tx_thread_user_priority = priority;
- thread_ptr -> tx_thread_time_slice = time_slice;
- thread_ptr -> tx_thread_new_time_slice = time_slice;
- thread_ptr -> tx_thread_inherit_priority = TX_MAX_PRIORITIES;
-
+#endif /* TXM_MODULE_MEMORY_PROTECTION */
+
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
/* Preemption-threshold is enabled, setup accordingly. */
@@ -381,9 +398,9 @@ ULONG status;
/* Preemption-threshold specified. Since specific preemption-threshold is not supported,
disable all preemption. */
- thread_ptr -> tx_thread_preempt_threshold = 0;
- thread_ptr -> tx_thread_user_preempt_threshold = 0;
- }
+ thread_ptr -> tx_thread_preempt_threshold = ((UINT) 0);
+ thread_ptr -> tx_thread_user_preempt_threshold = ((UINT) 0);
+ }
else
{
@@ -399,6 +416,9 @@ ULONG status;
/* Setup the necessary fields in the thread timer block. */
TX_THREAD_CREATE_TIMEOUT_SETUP(thread_ptr)
+ /* Perform any additional thread setup activities for tool or user purpose. */
+ TX_THREAD_CREATE_INTERNAL_EXTENSION(thread_ptr)
+
/* Setup pointer to the thread entry information structure, which will live at the top of each
module thread's stack. This will allow the module thread entry function to avoid direct
access to the actual thread control block. */
@@ -420,9 +440,9 @@ ULONG status;
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
thread_entry_info -> txm_module_thread_entry_info_exit_notify = thread_ptr -> tx_thread_entry_exit_notify;
-#else
+#else /* TX_DISABLE_NOTIFY_CALLBACKS */
thread_entry_info -> txm_module_thread_entry_info_exit_notify = TX_NULL;
-#endif
+#endif /* TX_DISABLE_NOTIFY_CALLBACKS */
if (thread_ptr -> tx_thread_entry == module_instance -> txm_module_instance_start_thread_entry)
thread_entry_info -> txm_module_thread_entry_info_start_thread = TX_TRUE;
else
@@ -457,7 +477,7 @@ ULONG status;
/* Place the thread on the list of created threads. First,
check for an empty list. */
- if (_tx_thread_created_count++ == 0)
+ if (_tx_thread_created_count == TX_EMPTY)
{
/* The created thread list is empty. Add thread to empty list. */
@@ -478,14 +498,17 @@ ULONG status;
/* Setup this thread's created links. */
thread_ptr -> tx_thread_created_previous = previous_thread;
- thread_ptr -> tx_thread_created_next = next_thread;
+ thread_ptr -> tx_thread_created_next = next_thread;
}
+ /* Increment the thread created count. */
+ _tx_thread_created_count++;
+
/* If trace is enabled, register this object. */
- TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_THREAD, thread_ptr, name, stack_start, stack_size)
+ TX_TRACE_OBJECT_REGISTER(TX_TRACE_OBJECT_TYPE_THREAD, thread_ptr, name_ptr, TX_POINTER_TO_ULONG_CONVERT(stack_start), stack_size)
/* If trace is enabled, insert this event into the trace buffer. */
- TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_CREATE, thread_ptr, priority, stack_start, stack_size, TX_TRACE_THREAD_EVENTS)
+ TX_TRACE_IN_LINE_INSERT(TX_TRACE_THREAD_CREATE, thread_ptr, priority, TX_POINTER_TO_ULONG_CONVERT(stack_start), stack_size, TX_TRACE_THREAD_EVENTS)
/* Register thread in the thread array structure. */
TX_EL_THREAD_REGISTER(thread_ptr)
@@ -493,13 +516,131 @@ ULONG status;
/* Log this kernel call. */
TX_EL_THREAD_CREATE_INSERT
+#ifdef TX_THREAD_SMP
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Temporarily disable preemption. */
+ _tx_thread_preempt_disable++;
+#endif
+
/* Determine if an automatic start was requested. If so, call the resume
thread function and then check for a preemption condition. */
if (auto_start == TX_AUTO_START)
{
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Resume the thread! */
+ _tx_thread_system_ni_resume(thread_ptr);
+
+#else
+
+ /* Restore previous interrupt posture. */
+ TX_RESTORE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Call the resume thread function to make this thread ready. */
+ _tx_thread_system_resume(thread_ptr);
+
+ /* Disable interrupts again. */
+ TX_DISABLE
+#endif
+
+ /* Determine if the execution list needs to be re-evaluated. */
+ if (_tx_thread_smp_current_state_get() >= TX_INITIALIZE_IN_PROGRESS)
+ {
+
#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
+ /* Clear the preemption bit maps, since nothing has yet run during initialization. */
+ TX_MEMSET(_tx_thread_preempted_maps, 0, sizeof(_tx_thread_preempted_maps));
+#if TX_MAX_PRIORITIES > 32
+ _tx_thread_preempted_map_active = ((ULONG) 0);
+#endif
+
+ /* Clear the entry in the preempted thread list. */
+ _tx_thread_preemption_threshold_list[priority] = TX_NULL;
+#endif
+
+ /* Set the pointer to the thread currently with preemption-threshold set to NULL. */
+ _tx_thread_preemption__threshold_scheduled = TX_NULL;
+
+#ifdef TX_THREAD_SMP_DEBUG_ENABLE
+
+ /* Debug entry. */
+ _tx_thread_smp_debug_entry_insert(12, 0, thread_ptr);
+#endif
+
+ /* Get the core index. */
+ core_index = TX_SMP_CORE_ID;
+
+ /* Call the rebalance routine. This routine maps cores and ready threads. */
+ _tx_thread_smp_rebalance_execute_list(core_index);
+
+#ifdef TX_THREAD_SMP_DEBUG_ENABLE
+
+ /* Debug entry. */
+ _tx_thread_smp_debug_entry_insert(13, 0, thread_ptr);
+#endif
+ }
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Restore interrupts. */
+ TX_RESTORE
+#endif
+ }
+ else
+ {
+
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Restore interrupts. */
+ TX_RESTORE
+#else
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Re-enable preemption. */
+ _tx_thread_preempt_disable--;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Check for preemption. */
+ _tx_thread_system_preempt_check();
+#endif
+ }
+
+#else /* TX_THREAD_SMP */
+
+#ifndef TX_NOT_INTERRUPTABLE
+
+ /* Temporarily disable preemption. */
+ _tx_thread_preempt_disable++;
+#endif
+
+ /* Determine if an automatic start was requested. If so, call the resume
+ thread function and then check for a preemption condition. */
+ if (auto_start == TX_AUTO_START)
+ {
+
/* Determine if the create call is being called from initialization. */
if (TX_THREAD_GET_SYSTEM_STATE() >= TX_INITIALIZE_IN_PROGRESS)
{
@@ -526,14 +667,13 @@ ULONG status;
initialization is complete. */
saved_thread_ptr -> tx_thread_preempt_threshold = saved_thread_ptr -> tx_thread_priority;
}
- }
+ }
else
{
/* Simply set the saved thread pointer to NULL. */
saved_thread_ptr = TX_NULL;
}
-#endif
#ifdef TX_NOT_INTERRUPTABLE
@@ -547,20 +687,15 @@ ULONG status;
TX_RESTORE
#else
- /* Temporarily disable preemption. */
- _tx_thread_preempt_disable++;
-
/* Restore previous interrupt posture. */
TX_RESTORE
/* Perform any additional activities for tool or user purpose. */
TX_THREAD_CREATE_EXTENSION(thread_ptr)
- /* Call the resume thread function to make this thread ready. */
+ /* Call the resume thread function to make this thread ready. */
_tx_thread_system_resume(thread_ptr);
#endif
-
-#ifndef TX_DISABLE_PREEMPTION_THRESHOLD
/* Determine if the thread's preemption-threshold needs to be restored. */
if (saved_thread_ptr != TX_NULL)
@@ -569,15 +704,41 @@ ULONG status;
/* Yes, restore the previous highest-priority thread's preemption-threshold. This
can only happen if this routine is called from initialization. */
saved_thread_ptr -> tx_thread_preempt_threshold = saved_threshold;
- }
-#endif
+ }
+ }
+ else
+ {
- /* Interrupts are already restored, simply return success. */
- return(TX_SUCCESS);
+#ifdef TX_NOT_INTERRUPTABLE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Restore interrupts. */
+ TX_RESTORE
+#else
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Perform any additional activities for tool or user purpose. */
+ TX_THREAD_CREATE_EXTENSION(thread_ptr)
+
+ /* Disable interrupts. */
+ TX_DISABLE
+
+ /* Re-enable preemption. */
+ _tx_thread_preempt_disable--;
+
+ /* Restore interrupts. */
+ TX_RESTORE
+
+ /* Check for preemption. */
+ _tx_thread_system_preempt_check();
+#endif
}
- /* Restore interrupts. */
- TX_RESTORE
+#endif /* TX_THREAD_SMP */
/* Return success. */
return(TX_SUCCESS);
diff --git a/common_smp/inc/tx_api.h b/common_smp/inc/tx_api.h
index f67d8fdc..36e9067e 100644
--- a/common_smp/inc/tx_api.h
+++ b/common_smp/inc/tx_api.h
@@ -26,7 +26,7 @@
/* APPLICATION INTERFACE DEFINITION RELEASE */
/* */
/* tx_api.h PORTABLE SMP */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -47,6 +47,9 @@
/* 10-16-2020 William E. Lamie Modified comment(s), and */
/* increased patch version, */
/* resulting in version 6.1.1 */
+/* 12-31-2020 William E. Lamie Modified comment(s), and */
+/* increased patch version, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
@@ -86,7 +89,7 @@ extern "C" {
#define AZURE_RTOS_THREADX
#define THREADX_MAJOR_VERSION 6
#define THREADX_MINOR_VERSION 1
-#define THREADX_PATCH_VERSION 1
+#define THREADX_PATCH_VERSION 3
/* Define the following symbol for backward compatibility */
#define EL_PRODUCT_THREADX
diff --git a/common_smp/src/tx_thread_create.c b/common_smp/src/tx_thread_create.c
index 63440bcc..70557627 100644
--- a/common_smp/src/tx_thread_create.c
+++ b/common_smp/src/tx_thread_create.c
@@ -12,8 +12,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** ThreadX Component */
+/** */
+/** ThreadX Component */
/** */
/** Thread */
/** */
@@ -32,58 +32,61 @@
#include "tx_initialize.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_thread_create PORTABLE SMP */
-/* 6.1 */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_thread_create PORTABLE SMP */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
-/* This function creates a thread and places it on the list of created */
-/* threads. */
-/* */
-/* INPUT */
-/* */
-/* thread_ptr Thread control block pointer */
-/* name_ptr Pointer to thread name string */
-/* entry_function Entry function of the thread */
-/* entry_input 32-bit input value to thread */
-/* stack_start Pointer to start of stack */
-/* stack_size Stack size in bytes */
-/* priority Priority of thread (0-31) */
+/* */
+/* This function creates a thread and places it on the list of created */
+/* threads. */
+/* */
+/* INPUT */
+/* */
+/* thread_ptr Thread control block pointer */
+/* name_ptr Pointer to thread name string */
+/* entry_function Entry function of the thread */
+/* entry_input 32-bit input value to thread */
+/* stack_start Pointer to start of stack */
+/* stack_size Stack size in bytes */
+/* priority Priority of thread (0-31) */
/* preempt_threshold Preemption threshold */
-/* time_slice Thread time-slice value */
-/* auto_start Automatic start selection */
-/* */
-/* OUTPUT */
-/* */
-/* return status Thread create return status */
-/* */
-/* CALLS */
-/* */
-/* _tx_thread_smp_rebalance_execute_list Rebalance execution list */
-/* _tx_thread_stack_build Build initial thread stack */
-/* _tx_thread_system_resume Resume automatic start thread */
-/* _tx_thread_system_ni_resume Noninterruptable resume thread*/
-/* */
-/* CALLED BY */
-/* */
-/* Application Code */
-/* _tx_timer_initialize Create system timer thread */
-/* */
-/* RELEASE HISTORY */
-/* */
+/* time_slice Thread time-slice value */
+/* auto_start Automatic start selection */
+/* */
+/* OUTPUT */
+/* */
+/* return status Thread create return status */
+/* */
+/* CALLS */
+/* */
+/* _tx_thread_smp_rebalance_execute_list Rebalance execution list */
+/* _tx_thread_stack_build Build initial thread stack */
+/* _tx_thread_system_resume Resume automatic start thread */
+/* _tx_thread_system_ni_resume Noninterruptable resume thread*/
+/* */
+/* CALLED BY */
+/* */
+/* Application Code */
+/* _tx_timer_initialize Create system timer thread */
+/* */
+/* RELEASE HISTORY */
+/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+/* 12-31-2020 Andres Mlinar Modified comment(s), */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
-UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, VOID (*entry_function)(ULONG id), ULONG entry_input,
+UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr,
+ VOID (*entry_function)(ULONG id), ULONG entry_input,
VOID *stack_start, ULONG stack_size, UINT priority, UINT preempt_threshold,
ULONG time_slice, UINT auto_start)
{
@@ -135,7 +138,7 @@ ALIGN_TYPE updated_stack_start;
list. */
/* Initialize thread control block to all zeros. */
- TX_MEMSET(thread_ptr, 0, (sizeof(TX_THREAD)));
+ TX_MEMSET(thread_ptr, 0, sizeof(TX_THREAD));
/* Place the supplied parameters into the thread's control block. */
thread_ptr -> tx_thread_name = name_ptr;
@@ -190,7 +193,7 @@ ALIGN_TYPE updated_stack_start;
disable all preemption. */
thread_ptr -> tx_thread_preempt_threshold = ((UINT) 0);
thread_ptr -> tx_thread_user_preempt_threshold = ((UINT) 0);
- }
+ }
else
{
@@ -207,7 +210,7 @@ ALIGN_TYPE updated_stack_start;
TX_THREAD_CREATE_TIMEOUT_SETUP(thread_ptr)
/* Perform any additional thread setup activities for tool or user purpose. */
- TX_THREAD_CREATE_INTERNAL_EXTENSION(thread_ptr)
+ TX_THREAD_CREATE_INTERNAL_EXTENSION(thread_ptr)
/* Call the target specific stack frame building routine to build the
thread's initial stack and to setup the actual stack pointer in the
@@ -249,7 +252,7 @@ ALIGN_TYPE updated_stack_start;
/* Setup this thread's created links. */
thread_ptr -> tx_thread_created_previous = previous_thread;
- thread_ptr -> tx_thread_created_next = next_thread;
+ thread_ptr -> tx_thread_created_next = next_thread;
}
/* Increment the thread created count. */
@@ -272,7 +275,7 @@ ALIGN_TYPE updated_stack_start;
/* Temporarily disable preemption. */
_tx_thread_preempt_disable++;
#endif
-
+
/* Determine if an automatic start was requested. If so, call the resume
thread function and then check for a preemption condition. */
if (auto_start == TX_AUTO_START)
@@ -294,13 +297,13 @@ ALIGN_TYPE updated_stack_start;
/* Perform any additional activities for tool or user purpose. */
TX_THREAD_CREATE_EXTENSION(thread_ptr)
- /* Call the resume thread function to make this thread ready. */
+ /* Call the resume thread function to make this thread ready. */
_tx_thread_system_resume(thread_ptr);
-
+
/* Disable interrupts again. */
TX_DISABLE
#endif
-
+
/* Determine if the execution list needs to be re-evaluated. */
if (_tx_thread_smp_current_state_get() >= TX_INITIALIZE_IN_PROGRESS)
{
@@ -325,7 +328,7 @@ ALIGN_TYPE updated_stack_start;
/* Debug entry. */
_tx_thread_smp_debug_entry_insert(12, 0, thread_ptr);
#endif
-
+
/* Get the core index. */
core_index = TX_SMP_CORE_ID;
@@ -337,7 +340,7 @@ ALIGN_TYPE updated_stack_start;
/* Debug entry. */
_tx_thread_smp_debug_entry_insert(13, 0, thread_ptr);
#endif
- }
+ }
#ifndef TX_NOT_INTERRUPTABLE
@@ -377,7 +380,7 @@ ALIGN_TYPE updated_stack_start;
#endif
}
- /* Always return a success. */
+ /* Return success. */
return(TX_SUCCESS);
}
diff --git a/common_smp/src/tx_thread_smp_high_level_initialize.c b/common_smp/src/tx_thread_smp_high_level_initialize.c
index 4dd63dce..b0082967 100644
--- a/common_smp/src/tx_thread_smp_high_level_initialize.c
+++ b/common_smp/src/tx_thread_smp_high_level_initialize.c
@@ -38,7 +38,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_smp_high_level_initialize PORTABLE SMP */
-/* 6.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -69,6 +69,10 @@
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+/* 12-31-2020 William E. Lamie Modified comments, added */
+/* cast to address a MISRA */
+/* compliant issue, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
void _tx_thread_smp_high_level_initialize(void)
@@ -95,7 +99,7 @@ void _tx_thread_smp_high_level_initialize(void)
TX_MEMSET(&_tx_thread_smp_protect_wait_list[0], 0xff, sizeof(_tx_thread_smp_protect_wait_list));
/* Set the wait list size so we can access it from assembly functions. */
- _tx_thread_smp_protect_wait_list_size = TX_THREAD_SMP_PROTECT_WAIT_LIST_SIZE;
+ _tx_thread_smp_protect_wait_list_size = ((ULONG) TX_THREAD_SMP_PROTECT_WAIT_LIST_SIZE);
#ifndef TX_THREAD_SMP_DYNAMIC_CORE_MAX
diff --git a/common_smp/src/tx_time_get.c b/common_smp/src/tx_time_get.c
index 695b502b..80cde187 100644
--- a/common_smp/src/tx_time_get.c
+++ b/common_smp/src/tx_time_get.c
@@ -12,8 +12,8 @@
/**************************************************************************/
/**************************************************************************/
-/** */
-/** ThreadX Component */
+/** */
+/** ThreadX Component */
/** */
/** Timer */
/** */
@@ -26,47 +26,48 @@
/* Include necessary system files. */
#include "tx_api.h"
-#ifdef TX_MISRA_ENABLE
#include "tx_trace.h"
#include "tx_timer.h"
-/**************************************************************************/
-/* */
-/* FUNCTION RELEASE */
-/* */
-/* _tx_time_get PORTABLE C */
-/* 6.1 */
+/**************************************************************************/
+/* */
+/* FUNCTION RELEASE */
+/* */
+/* _tx_time_get PORTABLE C */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
-/* */
-/* This function retrieves the internal, free-running, system clock */
-/* and returns it to the caller. */
-/* */
-/* INPUT */
-/* */
-/* None */
-/* */
-/* OUTPUT */
-/* */
-/* _tx_timer_system_clock Returns the system clock value */
-/* */
-/* CALLS */
-/* */
-/* None */
-/* */
-/* CALLED BY */
-/* */
-/* Application Code */
-/* */
-/* RELEASE HISTORY */
-/* */
+/* */
+/* This function retrieves the internal, free-running, system clock */
+/* and returns it to the caller. */
+/* */
+/* INPUT */
+/* */
+/* None */
+/* */
+/* OUTPUT */
+/* */
+/* _tx_timer_system_clock Returns the system clock value */
+/* */
+/* CALLS */
+/* */
+/* None */
+/* */
+/* CALLED BY */
+/* */
+/* Application Code */
+/* */
+/* RELEASE HISTORY */
+/* */
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+/* 12-31-2020 Andres Mlinar Modified comment(s), */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
ULONG _tx_time_get(VOID)
@@ -98,5 +99,4 @@ ULONG temp_time;
/* Return the time. */
return(temp_time);
}
-#endif /* TX_MISRA_ENABLE */
diff --git a/ports/arc_em/metaware/src/tx_timer_interrupt.s b/ports/arc_em/metaware/src/tx_timer_interrupt.s
index 67b06941..27141e01 100644
--- a/ports/arc_em/metaware/src/tx_timer_interrupt.s
+++ b/ports/arc_em/metaware/src/tx_timer_interrupt.s
@@ -35,7 +35,7 @@
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt ARCv2_EM/MetaWare */
-;/* 6.1 */
+;/* 6.1.3 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
@@ -72,6 +72,10 @@
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+;/* 12-31-2020 Scott Larson Modified comment(s), remove */
+;/* unneeded load of */
+;/* _tx_thread_preempt_disable, */
+;/* resulting in version 6.1.3 */
;/* */
;/**************************************************************************/
;VOID _tx_timer_interrupt(VOID)
@@ -187,7 +191,6 @@ __tx_something_expired:
; {
;
ld r2, [gp, _tx_timer_expired@sda] ; Pickup timer expired flag
- ld r4, [gp, _tx_thread_preempt_disable@sda] ; Pickup preempt disable
breq r2, 0, __tx_timer_dont_activate ; If not set, skip expiration processing
;
; /* Process the timer expiration. */
diff --git a/ports/arc_hs/metaware/src/tx_timer_interrupt.s b/ports/arc_hs/metaware/src/tx_timer_interrupt.s
index 663e9060..fdb70898 100644
--- a/ports/arc_hs/metaware/src/tx_timer_interrupt.s
+++ b/ports/arc_hs/metaware/src/tx_timer_interrupt.s
@@ -35,7 +35,7 @@
;/* FUNCTION RELEASE */
;/* */
;/* _tx_timer_interrupt ARC_HS/MetaWare */
-;/* 6.1 */
+;/* 6.1.3 */
;/* AUTHOR */
;/* */
;/* William E. Lamie, Microsoft Corporation */
@@ -72,6 +72,10 @@
;/* DATE NAME DESCRIPTION */
;/* */
;/* 09-30-2020 William E. Lamie Initial Version 6.1 */
+;/* 12-31-2020 Scott Larson Modified comment(s), remove */
+;/* unneeded load of */
+;/* _tx_thread_preempt_disable, */
+;/* resulting in version 6.1.3 */
;/* */
;/**************************************************************************/
;VOID _tx_timer_interrupt(VOID)
@@ -187,7 +191,6 @@ __tx_something_expired:
; {
;
ld r2, [gp, _tx_timer_expired@sda] ; Pickup timer expired flag
- ld r4, [gp, _tx_thread_preempt_disable@sda] ; Pickup preempt disable
breq r2, 0, __tx_timer_dont_activate ; If not set, skip expiration processing
;
; /* Process the timer expiration. */
diff --git a/ports/cortex_a35/ac6/example_build/sample_threadx/.settings/language.settings.xml b/ports/cortex_a35/ac6/example_build/sample_threadx/.settings/language.settings.xml
deleted file mode 100644
index 16ac1af8..00000000
--- a/ports/cortex_a35/ac6/example_build/sample_threadx/.settings/language.settings.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ports/cortex_a35/ac6/example_build/tx/.settings/language.settings.xml b/ports/cortex_a35/ac6/example_build/tx/.settings/language.settings.xml
deleted file mode 100644
index 830dd5dd..00000000
--- a/ports/cortex_a35/ac6/example_build/tx/.settings/language.settings.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ports/cortex_m23/gnu/example_build/build_threadx.bat b/ports/cortex_m23/gnu/example_build/build_threadx.bat
new file mode 100644
index 00000000..822d45f2
--- /dev/null
+++ b/ports/cortex_m23/gnu/example_build/build_threadx.bat
@@ -0,0 +1,235 @@
+del tx.a
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_initialize_low_level.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_context_restore.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_context_save.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_interrupt_control.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_interrupt_disable.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_interrupt_restore.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_schedule.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_secure_stack_allocate.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_secure_stack_free.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_stack_build.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_thread_system_return.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE ../src/tx_timer_interrupt.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../src/txe_thread_secure_stack_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../src/txe_thread_secure_stack_free.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../src/tx_thread_stack_error_handler.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../src/tx_thread_stack_error_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_block_release.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_pool_search.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_byte_release.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_event_flags_set_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_high_level.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_enter.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_initialize_kernel_setup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_mutex_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_flush.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_front_send.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_receive.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_queue_send_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_ceiling_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_cleanup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_semaphore_put_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_entry_exit_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_identify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_preemption_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_relinquish.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_reset.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_resume.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_shell_entry.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_sleep.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_stack_analyze.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_preempt_check.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_resume.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_system_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_terminate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_time_slice_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_timeout.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_thread_wait_abort.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_time_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_time_set.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_activate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_expiration_process.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_performance_system_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_activate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_system_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_timer_thread_entry.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_enable.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_disable.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_initialize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_interrupt_control.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_enter_insert.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_isr_exit_insert.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_register.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_object_unregister.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_user_event_insert.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_buffer_full_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_filter.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/tx_trace_event_unfilter.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_block_release.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_allocate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_pool_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_byte_release.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_event_flags_set_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_mutex_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_flush.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_front_send.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_receive.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_queue_send_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_ceiling_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_prioritize.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_semaphore_put_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_entry_exit_notify.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_info_get.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_preemption_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_priority_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_relinquish.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_reset.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_resume.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_suspend.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_terminate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_time_slice_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_thread_wait_abort.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_activate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_change.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_create.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_deactivate.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_delete.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m23 -DTX_SINGLE_MODE_NON_SECURE -I../../../../common/inc -I../inc ../../../../common/src/txe_timer_info_get.c
+arm-none-eabi-ar -r tx.a tx_thread_secure_stack_allocate.o txe_thread_secure_stack_allocate.o tx_thread_secure_stack_free.o txe_thread_secure_stack_free.o
+arm-none-eabi-ar -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
+arm-none-eabi-ar -r tx.a tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_initialize_low_level.o
+arm-none-eabi-ar -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
+arm-none-eabi-ar -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
+arm-none-eabi-ar -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
+arm-none-eabi-ar -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
+arm-none-eabi-ar -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
+arm-none-eabi-ar -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
+arm-none-eabi-ar -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
+arm-none-eabi-ar -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
+arm-none-eabi-ar -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
+arm-none-eabi-ar -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
+arm-none-eabi-ar -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
+arm-none-eabi-ar -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
+arm-none-eabi-ar -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
+arm-none-eabi-ar -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
+arm-none-eabi-ar -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
+arm-none-eabi-ar -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
+arm-none-eabi-ar -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
+arm-none-eabi-ar -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
+arm-none-eabi-ar -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
+arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
+arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
+arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
+arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
+arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
+arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
+arm-none-eabi-ar -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
+arm-none-eabi-ar -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
+arm-none-eabi-ar -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
+arm-none-eabi-ar -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
+arm-none-eabi-ar -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
+arm-none-eabi-ar -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
+arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
diff --git a/ports/cortex_m23/gnu/inc/tx_port.h b/ports/cortex_m23/gnu/inc/tx_port.h
index 69acde04..bb9c05a9 100644
--- a/ports/cortex_m23/gnu/inc/tx_port.h
+++ b/ports/cortex_m23/gnu/inc/tx_port.h
@@ -26,7 +26,7 @@
/* PORT SPECIFIC C INFORMATION RELEASE */
/* */
/* tx_port.h Cortex-M23/GNU */
-/* 6.1 */
+/* 6.1.3 */
/* */
/* AUTHOR */
/* */
@@ -48,6 +48,10 @@
/* DATE NAME DESCRIPTION */
/* */
/* 09-30-2020 Scott Larson Initial Version 6.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), */
+/* remove unneeded headers, */
+/* use builtins, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
@@ -67,8 +71,6 @@
#include
#include
-#include
-#include "ARMCM23_TZ.h" /* For intrinsic functions. */
/* Define ThreadX basic types for this port. */
@@ -275,8 +277,6 @@ ULONG _tx_misra_time_stamp_get(VOID);
#ifndef TX_MISRA_ENABLE
-//register unsigned int _ipsr __asm ("MRS %[result], ipsr" : [result] "=r" (_ipsr) : );
-inline static unsigned int _get_ipsr(void);
inline static unsigned int _get_ipsr(void)
{
unsigned int _ipsr;
@@ -352,7 +352,7 @@ extern void _tx_thread_secure_stack_initialize(void);
#ifndef TX_DISABLE_INLINE
-#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m)));
+#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __builtin_ctz(m);
#endif
@@ -364,41 +364,73 @@ extern void _tx_thread_secure_stack_initialize(void);
is used to define a local function save area for the disable and restore
macros. */
-#ifdef TX_DISABLE_INLINE
+#ifndef TX_DISABLE_INLINE
-UINT _tx_thread_interrupt_disable(VOID);
-VOID _tx_thread_interrupt_restore(UINT previous_posture);
+/* Define GNU specific macros, with in-line assembly for performance. */
-#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void)
+{
-#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+unsigned int primask_value;
-#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+ __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
+ __asm__ volatile (" CPSID i" : : : "memory" );
+ return(primask_value);
+}
-#else
+__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value)
+{
-#define TX_INTERRUPT_SAVE_AREA unsigned int was_masked;
-#define TX_DISABLE was_masked = __disable_irq();
-#define TX_RESTORE if (was_masked == 0) __enable_irq();
+ __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" );
+}
+
+__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void)
+{
+
+unsigned int primask_value;
+
+ __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) );
+ return(primask_value);
+}
+
+__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void)
+{
+
+ __asm__ volatile (" CPSIE i": : : "memory" );
+}
+
+
+__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void)
+{
+unsigned int interrupt_save;
+
+ *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
+ if (_get_ipsr() == 0)
+ {
+ interrupt_save = __get_primask_value();
+ __enable_interrupts();
+ __restore_interrupts(interrupt_save);
+ }
+}
+
+
+#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
+
+#define TX_DISABLE interrupt_save = __disable_interrupts();
+#define TX_RESTORE __restore_interrupts(interrupt_save);
+
+
+/* Redefine _tx_thread_system_return for improved performance. */
#define _tx_thread_system_return _tx_thread_system_return_inline
-static void _tx_thread_system_return_inline(void)
-{
-unsigned int was_masked;
+#else
+#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
- /* Set PendSV to invoke ThreadX scheduler. */
- *((ULONG *) 0xE000ED04) = ((ULONG) 0x10000000);
- if (_get_ipsr() == 0)
- {
- was_masked = __disable_irq();
- __enable_irq();
- if (was_masked != 0)
- __disable_irq();
- }
-}
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
+#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
#endif
@@ -406,7 +438,7 @@ unsigned int was_masked;
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1 *";
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M23/GNU Version 6.1.3 *";
#else
#ifdef TX_MISRA_ENABLE
extern CHAR _tx_version_id[100];
diff --git a/ports/cortex_m23/gnu/readme_threadx.txt b/ports/cortex_m23/gnu/readme_threadx.txt
index fa581684..e5dacfec 100644
--- a/ports/cortex_m23/gnu/readme_threadx.txt
+++ b/ports/cortex_m23/gnu/readme_threadx.txt
@@ -5,12 +5,12 @@
1. Building the ThreadX run-time Library
-
+An example .bat file is in the example_build directory.
2. Demonstration System
-
+No demonstration example is provided.
3. System Initialization
@@ -127,6 +127,18 @@ For generic code revision information, please refer to the readme_threadx_generi
file, which is included in your distribution. The following details the revision
information associated with this specific port of ThreadX:
+12-31-2020 The following files were
+ changed/added for port specific version 6.1.3:
+
+
+ tx_port.h Remove unneeded include files,
+ use builtin functions,
+ modified comments.
+
+ tx_thread_secure_stack.c Remove unneeded include file,
+ use inline get/set functions,
+ modified comments.
+
09-30-2020 Initial ThreadX 6.1 version for Cortex-M23 using GNU tools.
diff --git a/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c b/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c
index 9ca7ccff..0e8cbde0 100644
--- a/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c
+++ b/ports/cortex_m23/gnu/src/tx_thread_secure_stack.c
@@ -29,7 +29,6 @@
#define TX_SOURCE_CODE
-#include "ARMCM23_TZ.h" /* For intrinsic functions. */
#include "tx_secure_interface.h" /* Interface for NS code. */
/* Minimum size of secure stack. */
@@ -63,7 +62,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_initialize Cortex-M23/GNU */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -82,10 +81,7 @@ typedef struct TX_THREAD_SECURE_STACK_INFO_STRUCT
/* */
/* CALLS */
/* */
-/* __get_CONTROL Intrinsic to get CONTROL */
-/* __set_CONTROL Intrinsic to set CONTROL */
-/* __set_PSPLIM Intrinsic to set PSP limit */
-/* __set_PSP Intrinsic to set PSP */
+/* None */
/* */
/* CALLED BY */
/* */
@@ -98,19 +94,25 @@ 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 */
+/* 12-31-2020 Scott Larson Modified comment(s), and */
+/* fixed M23 GCC build, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_initialize(void)
{
+ ULONG control;
/* Set secure mode to use PSP. */
- __set_CONTROL(__get_CONTROL() | 2);
+ 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. */
- __set_PSPLIM(0);
- __set_PSP(0);
+ asm volatile("MSR PSPLIM, %0" :: "r" (0));
+ asm volatile("MSR PSP, %0" :: "r" (0));
return;
}
@@ -122,7 +124,7 @@ void _tx_thread_secure_stack_initialize(void)
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_allocate Cortex-M23/GNU */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -145,13 +147,9 @@ void _tx_thread_secure_stack_initialize(void)
/* */
/* 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 */
/* */
/* CALLED BY */
/* */
@@ -165,6 +163,10 @@ void _tx_thread_secure_stack_initialize(void)
/* 10-16-2020 Scott Larson Modified comment(s), */
/* added stack sealing, */
/* resulting in version 6.1.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), and */
+/* fixed M23 GCC build, */
+/* resulting in version 6.1.3 */
+
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -173,12 +175,14 @@ UINT _tx_thread_secure_mode_stack_allocate(TX_THREAD *thread_ptr, ULONG stack
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
UCHAR *stack_mem;
-ULONG sp;
+ULONG ipsr;
+ULONG psplim_ns;
status = TX_SUCCESS;
/* Make sure function is called from interrupt (threads should not call). */
- if (__get_IPSR() == 0)
+ asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
+ if (ipsr == 0)
{
status = TX_CALLER_ERROR;
}
@@ -217,14 +221,13 @@ ULONG sp;
/* 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))
+ /* 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)
{
/* 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));
+ 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)));
}
}
@@ -252,7 +255,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_mode_stack_free Cortex-M23/GNU */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -273,7 +276,6 @@ ULONG sp;
/* */
/* CALLS */
/* */
-/* __get_IPSR Intrinsic to get IPSR */
/* free Compiler's free() function */
/* */
/* CALLED BY */
@@ -287,6 +289,9 @@ 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 */
+/* 12-31-2020 Scott Larson Modified comment(s), and */
+/* fixed M23 GCC build, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -294,14 +299,16 @@ UINT _tx_thread_secure_mode_stack_free(TX_THREAD *thread_ptr)
{
UINT status;
TX_THREAD_SECURE_STACK_INFO *info_ptr;
-
+ULONG ipsr;
+
status = TX_SUCCESS;
/* Pickup stack info from thread. */
info_ptr = thread_ptr -> tx_thread_secure_stack_context;
/* Make sure function is called from interrupt (threads should not call). */
- if (__get_IPSR() == 0)
+ asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
+ if (ipsr == 0)
{
status = TX_CALLER_ERROR;
}
@@ -335,7 +342,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_save Cortex-M23/GNU */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -354,10 +361,7 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* */
/* CALLS */
/* */
-/* __get_IPSR Intrinsic to get IPSR */
-/* __get_PSP Intrinsic to get PSP */
-/* __set_PSPLIM Intrinsic to set PSP limit */
-/* __set_PSP Intrinsic to set PSP */
+/* None */
/* */
/* CALLED BY */
/* */
@@ -370,6 +374,9 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
/* 09-30-2020 Scott Larson Initial Version 6.1 */
/* 10-16-2020 Scott Larson Modified comment(s), */
/* resulting in version 6.1.1 */
+/* 12-31-2020 Scott Larson Modified comment(s), and */
+/* fixed M23 GCC build, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
@@ -377,9 +384,11 @@ void _tx_thread_secure_stack_context_save(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
ULONG sp;
-
+ULONG ipsr;
+
/* This function should be called from scheduler only. */
- if (__get_IPSR() == 0)
+ asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
+ if (ipsr == 0)
{
return;
}
@@ -394,7 +403,7 @@ ULONG sp;
}
/* Check that stack pointer is in range */
- sp = __get_PSP();
+ asm volatile("MRS %0, PSP" : "=r" (sp)); /* Get PSP register. */
if ((sp < (ULONG)info_ptr -> tx_thread_secure_stack_limit) ||
(sp > (ULONG)info_ptr -> tx_thread_secure_stack_start))
{
@@ -406,8 +415,8 @@ ULONG 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);
+ asm volatile("MSR PSPLIM, %0" :: "r" (0));
+ asm volatile("MSR PSP, %0" :: "r" (0));
return;
}
@@ -419,7 +428,7 @@ ULONG sp;
/* FUNCTION RELEASE */
/* */
/* _tx_thread_secure_stack_context_restore Cortex-M23/GNU */
-/* 6.1.1 */
+/* 6.1.3 */
/* AUTHOR */
/* */
/* Scott Larson, Microsoft Corporation */
@@ -438,9 +447,7 @@ ULONG sp;
/* */
/* CALLS */
/* */
-/* __get_IPSR Intrinsic to get IPSR */
-/* __set_PSPLIM Intrinsic to set PSP limit */
-/* __set_PSP Intrinsic to set PSP */
+/* None */
/* */
/* CALLED BY */
/* */
@@ -453,15 +460,20 @@ 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 */
+/* 12-31-2020 Scott Larson Modified comment(s), and */
+/* fixed M23 GCC build, */
+/* resulting in version 6.1.3 */
/* */
/**************************************************************************/
__attribute__((cmse_nonsecure_entry))
void _tx_thread_secure_stack_context_restore(TX_THREAD *thread_ptr)
{
TX_THREAD_SECURE_STACK_INFO *info_ptr;
+ULONG ipsr;
/* This function should be called from scheduler only. */
- if (__get_IPSR() == 0)
+ asm volatile("MRS %0, IPSR" : "=r" (ipsr)); /* Get IPSR register. */
+ if (ipsr == 0)
{
return;
}
@@ -476,8 +488,8 @@ TX_THREAD_SECURE_STACK_INFO *info_ptr;
}
/* 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);
+ 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/rxv2/ccrx/inc/tx_port.h b/ports/rxv2/ccrx/inc/tx_port.h
new file mode 100644
index 00000000..21931297
--- /dev/null
+++ b/ports/rxv2/ccrx/inc/tx_port.h
@@ -0,0 +1,281 @@
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RX/CCRX */
+/* 6.1.3 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Express Logic, Inc. */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+/* UINT _tx_thread_interrupt_control(UINT new_posture); */
+
+#pragma inline_asm _tx_thread_interrupt_disable
+static UINT _tx_thread_interrupt_disable(void){
+ MVFC PSW,R1 ;
+ CLRPSW I ;
+}
+
+
+#pragma inline_asm _tx_thread_interrupt_restore
+static void _tx_thread_interrupt_restore(UINT old_posture){
+ MVFC PSW, R2 ;
+ BTST #16,r1 ;
+ BMC #16,r2 ;
+ MVTC r2,PSW ;
+}
+
+#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ UINT interrupt_save;
+
+ interrupt_save = _tx_thread_interrupt_disable();
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ _tx_thread_interrupt_restore(interrupt_save);
+}
+
+
+#ifndef TX_THREAD_GET_SYSTEM_STATE
+
+#pragma inline_asm _get_psw
+static UINT _get_psw(void){
+ MVFC PSW,R1 ;
+}
+
+extern volatile ULONG _tx_thread_system_state;
+#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~_get_psw()) & (1u << 17u)))
+#endif
+
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RX/CCRX Version 6.1.3 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/rxv2/ccrx/readme_threadx.txt b/ports/rxv2/ccrx/readme_threadx.txt
new file mode 100644
index 00000000..c496fbb3
--- /dev/null
+++ b/ports/rxv2/ccrx/readme_threadx.txt
@@ -0,0 +1,175 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv2
+
+ Using the CC-RX Tools
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2.
+
+
+2. Demonstration System
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2
+
+
+3. System Initialization
+
+The system entry point using Renesas tools is at the label _PowerON_Reset_PC.
+Use the resetprg.c file that comes with your release. Most notable is that Threadx
+applications run in supervisor mode and do not use user mode. Hence switching to
+user mode has been commented out.
+
+The vector area is set up using either intprg.c or in the file tx_initialize_low_level.src.
+The file tx_initialize_low_level.src is responsible for setting up various system data
+structures, interrupt vectors, and a periodic timer. This is the ideal place add
+application specific hardware initialization code.
+
+ThreadX utilizes CMT0 as a periodic timer interrupt source. The CMT0 interrupt is
+typically setup for 10ms periodic interrupts and the interrupt priority level is set to
+level 7. You may change any of the timer parameters to suit your needs.
+
+In addition, _tx_initialize_low_level determines the first available address for use by
+the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define(). The mechanism is implemented by creating the
+FREEMEM section, this section should be linked last in the RAM area. tx_initialize_low_level
+will pick up the starting label of this section and put it in the global variable:
+_tx_initialize_unused_memory
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x08 ACC1
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x2C FPSW
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default ccrx does not save the state of the accumulator registers ACC0 and ACC1
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of those registers could be corrupted. Saving and restoring of the acummulators
+can be enabled by adding the -save_acc command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler
+optimizations. This makes it easy to debug because you can trace or set
+breakpoints inside of ThreadX itself. Of course, this costs some
+performance. To make ThreadX run faster, you can change the ThreadX Library
+project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by
+compiling your application code with the symbol TX_DISABLE_ERROR_CHECKING
+defined before tx_api.h is included.
+
+
+6. Timer Processing
+
+Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effectd but doing so may may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv2 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+
+* in tx_port.h, change around line 183
+change #define TX_THREAD_EXTENSION_3
+into #include "tx_execution_profile.h"
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 74:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
+ unsigned long long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \
+ unsigned long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+
+12-31-2020 Initial ThreadX release for the RXv2 using CC-RXX tools, version 6.1.3
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
+
+
+
+www.expresslogic.com
\ No newline at end of file
diff --git a/ports/rxv2/ccrx/src/tx_initialize_low_level.src b/ports/rxv2/ccrx/src/tx_initialize_low_level.src
new file mode 100644
index 00000000..72b297bf
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_initialize_low_level.src
@@ -0,0 +1,101 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ .GLB __tx_initialize_unused_memory
+
+ IPR03 .EQU 87303H
+ IEN03 .EQU 87203H
+
+ .SECTION P,CODE
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+
+ .GLB __tx_initialize_low_level
+__tx_initialize_low_level:
+;
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #free_mem_start, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory,R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #IPR03, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #IEN03,r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+ .SECTION FREEMEM ,DATA, ALIGN=4
+free_mem_start:
+ .BLKL 8 ; this section is last in the link map so we can access the end of RAM memory
+
+ .END
diff --git a/ports/rxv2/ccrx/src/tx_thread_context_restore.src b/ports/rxv2/ccrx/src/tx_thread_context_restore.src
new file mode 100644
index 00000000..9601dfda
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_context_restore.src
@@ -0,0 +1,207 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .GLB __tx_thread_system_state
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_thread_system_stack_ptr
+ .GLB __tx_thread_execute_ptr
+ .GLB __tx_timer_time_slice
+ .GLB __tx_thread_schedule
+ .GLB __tx_thread_preempt_disable
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_restore(VOID)
+;{
+ .GLB __tx_thread_context_restore
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACGU #0, A1, R4 ; Save accumulators.
+ MVFACHI #0, A1, R5
+ MVFACLO #0, A1, R6
+ PUSHM R4-R6
+ MVFACGU #0, A0, R4
+ MVFACHI #0, A0, R5
+ MVFACLO #0, A0, R6
+ PUSHM R4-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ .END
+
diff --git a/ports/rxv2/ccrx/src/tx_thread_context_save.src b/ports/rxv2/ccrx/src/tx_thread_context_save.src
new file mode 100644
index 00000000..26e94078
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_context_save.src
@@ -0,0 +1,171 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+ .GLB __tx_thread_system_state
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_thread_system_stack_ptr
+
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ .GLB __tx_thread_context_save
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+ MVFC FPSW, R3
+ MOV.L R3, [-R1] ; save FPSW on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ .END
+
diff --git a/ports/rxv2/ccrx/src/tx_thread_interrupt_control.src b/ports/rxv2/ccrx/src/tx_thread_interrupt_control.src
new file mode 100644
index 00000000..39168c1d
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_interrupt_control.src
@@ -0,0 +1,96 @@
+;/**************************************************************************/
+;/* */
+;/* 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"
+;
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+
+.GLB __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ .END
+
diff --git a/ports/rxv2/ccrx/src/tx_thread_schedule.src b/ports/rxv2/ccrx/src/tx_thread_schedule.src
new file mode 100644
index 00000000..a34c12f5
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_schedule.src
@@ -0,0 +1,180 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .GLB __tx_thread_execute_ptr
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_timer_time_slice
+;
+ .SECTION P,CODE
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ .GLB __tx_thread_schedule
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R3 ; Restore accumulators.
+ MVTACLO R3, A0
+ MVTACHI R2, A0
+ MVTACGU R1, A0
+ POPM R1-R3
+ MVTACLO R3, A1
+ MVTACHI R2, A1
+ MVTACGU R1, A1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPC FPSW
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+
+.GLB __tx_thread_context_save
+.GLB __tx_thread_context_restore
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+.RVECTOR 27, _tx_software_interrupt_entry
+.GLB _tx_software_interrupt_entry
+_tx_software_interrupt_entry:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ .END
diff --git a/ports/rxv2/ccrx/src/tx_thread_stack_build.src b/ports/rxv2/ccrx/src/tx_thread_stack_build.src
new file mode 100644
index 00000000..38da71c9
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_stack_build.src
@@ -0,0 +1,155 @@
+;/**************************************************************************/
+;/* */
+;/* 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"
+;
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+;{
+ .GLB __tx_thread_stack_build
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; ACC1
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; FPSW
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MVFC FPSW, r4
+ MOV.L R4, [-R3] ; initial FPSW
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 1
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+ .END
+
diff --git a/ports/rxv2/ccrx/src/tx_thread_system_return.src b/ports/rxv2/ccrx/src/tx_thread_system_return.src
new file mode 100644
index 00000000..fb70a970
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_thread_system_return.src
@@ -0,0 +1,127 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .GLB __tx_thread_current_ptr
+ .GLB __tx_timer_time_slice
+ .GLB __tx_thread_schedule
+
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_system_return(VOID)
+;{
+ .GLB __tx_thread_system_return
+__tx_thread_system_return:
+;
+; /* Save call save registers on the stack. */
+;
+ PUSHM R6-R13
+ PUSHC PSW
+ MOV.L #0, R1
+ PUSH.L R1 ; solicited stack frame
+;
+; /* Lockout interrupts. */
+;
+ CLRPSW I ; Lockout interrupts
+;
+; /* Save current stack in current Thread controle block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
+ MOV.L #__tx_thread_current_ptr, R2
+ MOV.L [R2], R3
+ MOV.L R0, 8[R3]
+
+ MOV.L #__tx_timer_time_slice, R4
+ MOV.L [R4], R5
+
+; /* Determine if the time-slice is active. */
+; if (_tx_timer_time_slice)
+; {
+;
+ CMP #0,R5 ; Is a time-slice present?
+ BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice
+;
+; /* Save time-slice for the thread and clear the current time-slice. */
+ ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ MOV.L R5,24[R3]
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R1, [R4] ; Disable the time-slice
+;
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Clear the current thread pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV.L R1, [R2]
+ BRA __tx_thread_schedule
+;}
+ .END
+
diff --git a/ports/rxv2/ccrx/src/tx_timer_interrupt.src b/ports/rxv2/ccrx/src/tx_timer_interrupt.src
new file mode 100644
index 00000000..cf88b6c1
--- /dev/null
+++ b/ports/rxv2/ccrx/src/tx_timer_interrupt.src
@@ -0,0 +1,251 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/** Timer */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_timer.h"
+;#include "tx_thread.h"
+;
+;
+;Define Assembly language external references...
+;
+ .GLB __tx_timer_time_slice
+ .GLB __tx_timer_system_clock
+ .GLB __tx_timer_current_ptr
+ .GLB __tx_timer_list_start
+ .GLB __tx_timer_list_end
+ .GLB __tx_timer_expired_time_slice
+ .GLB __tx_timer_expired
+ .GLB __tx_timer_expiration_process
+ .GLB __tx_thread_context_save
+ .GLB __tx_thread_time_slice
+ .GLB __tx_thread_context_restore
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RX/CCRX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_timer_interrupt(VOID)
+;{
+ .GLB __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+
+ .END
+
diff --git a/ports/rxv2/gnu/inc/tx_port.h b/ports/rxv2/gnu/inc/tx_port.h
new file mode 100644
index 00000000..57841625
--- /dev/null
+++ b/ports/rxv2/gnu/inc/tx_port.h
@@ -0,0 +1,264 @@
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RX/GNURX */
+/* 6.1.3 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Express Logic, Inc. */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+#include
+//#include
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+#ifdef TX_DISABLE_INLINE
+
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
+
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+#else
+
+#define TX_INTERRUPT_SAVE_AREA UCHAR interrupt_save;
+#define TX_DISABLE {interrupt_save = ((UCHAR)__builtin_rx_mvfc(0u) && 0x8u); __builtin_rx_clrpsw(8u);};
+#define TX_RESTORE {if(interrupt_save != 0u) {__builtin_rx_setpsw(8u);}};
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ TX_INTERRUPT_SAVE_AREA
+
+ TX_DISABLE
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ TX_RESTORE
+}
+
+#endif
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RX/GNURX Version 6.1.3 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+#endif
+
diff --git a/ports/rxv2/gnu/readme_threadx.txt b/ports/rxv2/gnu/readme_threadx.txt
new file mode 100644
index 00000000..5baf5961
--- /dev/null
+++ b/ports/rxv2/gnu/readme_threadx.txt
@@ -0,0 +1,168 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv2
+
+ Using the GNU Tools
+
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2.
+
+
+2. Demonstration System
+
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2.
+
+
+3. System Initialization
+
+The system entry point using the GNU tools is at the label _PowerON_Reset.
+
+The vector area is setup in the file tx_initialize_low_level.S. This file is also
+responsible for setting up various system data structures, interrupt vectors, and
+the periodic timer interrupt. This file is also an ideal place to add additional hardware
+initialization code.
+
+The ThreadX demonstration for the RXv2 utilizes CMT0 as a periodic timer interrupt
+source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the
+interrupt priority level is set to level 7. You may change any of the timer
+parameters as needed. Increasing the timer interrupt frequency increases the overhead
+of the timer handling code on the system.
+
+In addition, _tx_initialize_low_level determines the first available address for use
+by the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define. The first available memory is determined
+by the location of the '_end' label the is defined in the linker script.
+'_end' should reference the first memory AFTER all other RAM
+sections in your linker control file.
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x08 ACC1
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x2C FPSW
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default GNURX does not save the state of the accumulator registers ACC0 and ACC1
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of those registers could be corrupted. Saving and restoring of the acummulators
+can be enabled by adding the -msave-acc-in-interrupts command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler optimizations. This
+makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself.
+Of course, this costs some performance. To make ThreadX run faster, you can change the
+ThreadX Library project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by compiling your
+application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h
+is included.
+
+
+6. Timer Processing
+
+Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effectd but doing so may may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv2 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+
+* in tx_port.h, change around line 183
+change #define TX_THREAD_EXTENSION_3
+into #include "tx_execution_profile.h"
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 74:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
+ unsigned long long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \
+ unsigned long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+
+12-31-2020 Initial ThreadX release for the RXv2 using GNURX tools, version 6.1.3
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
+
diff --git a/ports/rxv2/gnu/src/tx_initialize_low_level.S b/ports/rxv2/gnu/src/tx_initialize_low_level.S
new file mode 100644
index 00000000..197ae936
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_initialize_low_level.S
@@ -0,0 +1,93 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ .text
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+ .global __tx_initialize_low_level
+__tx_initialize_low_level:
+
+;
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #_end, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory, R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #0x87303, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #0x87203,r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+
+ .end
diff --git a/ports/rxv2/gnu/src/tx_thread_context_restore.S b/ports/rxv2/gnu/src/tx_thread_context_restore.S
new file mode 100644
index 00000000..c2799838
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_context_restore.S
@@ -0,0 +1,207 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .global __tx_thread_system_state
+ .global __tx_thread_current_ptr
+ .global __tx_thread_system_stack_ptr
+ .global __tx_thread_execute_ptr
+ .global __tx_timer_time_slice
+ .global __tx_thread_schedule
+ .global __tx_thread_preempt_disable
+
+ .text
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_restore(VOID)
+;{
+ .global __tx_thread_context_restore
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACGU #0, A1, R4 ; Save accumulators.
+ MVFACHI #0, A1, R5
+ MVFACLO #0, A1, R6
+ PUSHM R4-R6
+ MVFACGU #0, A0, R4
+ MVFACHI #0, A0, R5
+ MVFACLO #0, A0, R6
+ PUSHM R4-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ .end
diff --git a/ports/rxv2/gnu/src/tx_thread_context_save.S b/ports/rxv2/gnu/src/tx_thread_context_save.S
new file mode 100644
index 00000000..cae38615
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_context_save.S
@@ -0,0 +1,171 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+ .global __tx_thread_system_state
+ .global __tx_thread_current_ptr
+ .global __tx_thread_system_stack_ptr
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ .global __tx_thread_context_save
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+ MVFC FPSW, R3
+ MOV.L R3, [-R1] ; save FPSW on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ .end
+
diff --git a/ports/rxv2/gnu/src/tx_thread_interrupt_control.S b/ports/rxv2/gnu/src/tx_thread_interrupt_control.S
new file mode 100644
index 00000000..096c0568
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_interrupt_control.S
@@ -0,0 +1,96 @@
+;/**************************************************************************/
+;/* */
+;/* 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"
+;
+;
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+
+ .global __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ .end
+
diff --git a/ports/rxv2/gnu/src/tx_thread_schedule.S b/ports/rxv2/gnu/src/tx_thread_schedule.S
new file mode 100644
index 00000000..c48840e7
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_schedule.S
@@ -0,0 +1,180 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .global __tx_thread_execute_ptr
+ .global __tx_thread_current_ptr
+ .global __tx_timer_time_slice
+;
+ .text
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ .global __tx_thread_schedule
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R3 ; Restore accumulators.
+ MVTACLO R3, A0
+ MVTACHI R2, A0
+ MVTACGU R1, A0
+ POPM R1-R3
+ MVTACLO R3, A1
+ MVTACHI R2, A1
+ MVTACGU R1, A1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPC FPSW
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+
+.global __tx_thread_context_save
+.global __tx_thread_context_restore
+
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+.global $tableentry$27$.rvectors
+$tableentry$27$.rvectors:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ .end
diff --git a/ports/rxv2/gnu/src/tx_thread_stack_build.S b/ports/rxv2/gnu/src/tx_thread_stack_build.S
new file mode 100644
index 00000000..752372bf
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_stack_build.S
@@ -0,0 +1,155 @@
+;/**************************************************************************/
+;/* */
+;/* 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"
+;
+;
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+;{
+ .global __tx_thread_stack_build
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; ACC1
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; FPSW
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MVFC FPSW, r4
+ MOV.L R4, [-R3] ; initial FPSW
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 1
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+ .end
+
diff --git a/ports/rxv2/gnu/src/tx_thread_system_return.S b/ports/rxv2/gnu/src/tx_thread_system_return.S
new file mode 100644
index 00000000..baa5314a
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_thread_system_return.S
@@ -0,0 +1,127 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ .global __tx_thread_current_ptr
+ .global __tx_timer_time_slice
+ .global __tx_thread_schedule
+
+ .text
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_system_return(VOID)
+;{
+ .GLB __tx_thread_system_return
+__tx_thread_system_return:
+;
+; /* Save call save registers on the stack. */
+;
+ PUSHM R6-R13
+ PUSHC PSW
+ MOV.L #0, R1
+ PUSH.L R1 ; solicited stack frame
+;
+; /* Lockout interrupts. */
+;
+ CLRPSW I ; Lockout interrupts
+;
+; /* Save current stack in current Thread controle block. */
+; _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
+ MOV.L #__tx_thread_current_ptr, R2
+ MOV.L [R2], R3
+ MOV.L R0, 8[R3]
+
+ MOV.L #__tx_timer_time_slice, R4
+ MOV.L [R4], R5
+
+; /* Determine if the time-slice is active. */
+; if (_tx_timer_time_slice)
+; {
+;
+ CMP #0,R5 ; Is a time-slice present?
+ BEQ __tx_thread_dont_save_ts ; No, don't save the time-slice
+;
+; /* Save time-slice for the thread and clear the current time-slice. */
+ ; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ MOV.L R5,24[R3]
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R1, [R4] ; Disable the time-slice
+;
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Clear the current thread pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+;
+ MOV.L R1, [R2]
+ BRA __tx_thread_schedule
+;}
+ .end
+
diff --git a/ports/rxv2/gnu/src/tx_timer_interrupt.S b/ports/rxv2/gnu/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..3511e2c8
--- /dev/null
+++ b/ports/rxv2/gnu/src/tx_timer_interrupt.S
@@ -0,0 +1,251 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/** Timer */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+;#define TX_SOURCE_CODE
+;
+;
+;/* Include necessary system files. */
+;
+;#include "tx_api.h"
+;#include "tx_timer.h"
+;#include "tx_thread.h"
+;
+;
+;Define Assembly language external references...
+;
+ .global __tx_timer_time_slice
+ .global __tx_timer_system_clock
+ .global __tx_timer_current_ptr
+ .global __tx_timer_list_start
+ .global __tx_timer_list_end
+ .global __tx_timer_expired_time_slice
+ .global __tx_timer_expired
+ .global __tx_timer_expiration_process
+ .global __tx_thread_context_save
+ .global __tx_thread_time_slice
+ .global __tx_thread_context_restore
+;
+ .SECTION P,CODE
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RX/GNURX */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_timer_interrupt(VOID)
+;{
+ .global __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+
+ .end
+
diff --git a/ports/rxv2/iar/inc/tx_port.h b/ports/rxv2/iar/inc/tx_port.h
new file mode 100644
index 00000000..14b9728f
--- /dev/null
+++ b/ports/rxv2/iar/inc/tx_port.h
@@ -0,0 +1,273 @@
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port.h RX/IAR */
+/* 6.1.3 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Express Logic, Inc. */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+#include
+#include
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+
+
+/* Yes, include the user defines in tx_user.h. The defines in this file may
+ alternately be defined on the command line. */
+
+#include "tx_user.h"
+#endif
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/* Define the minimum stack for a ThreadX thread on this processor. If the size supplied during
+ thread creation is less than this value, the thread create call will return an error. */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK 256 /* Minimum stack size for this port */
+#endif
+
+
+/* Define the system timer thread's default stack size and priority. These are only applicable
+ if TX_TIMER_PROCESS_IN_ISR is not defined. */
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */
+#endif
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/* Define the port specific options for the _tx_build_options variable. This variable indicates
+ how the ThreadX library was built. */
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS 0
+
+
+/* Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call. */
+
+#define TX_INLINE_INITIALIZATION
+
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/* Define the TX_THREAD control block extensions for this port. The main reason
+ for the multiple macros is so that backward compatibility can be maintained with
+ existing ThreadX kernel awareness modules. */
+
+#define TX_THREAD_EXTENSION_0
+#define TX_THREAD_EXTENSION_1
+#define TX_THREAD_EXTENSION_2
+#define TX_THREAD_EXTENSION_3
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+/* Define ThreadX interrupt lockout and restore macros for protection on
+ access of critical kernel information. The restore interrupt macro must
+ restore the interrupt posture of the running thread prior to the value
+ present prior to the disable macro. In most cases, the save area macro
+ is used to define a local function save area for the disable and restore
+ macros. */
+
+#ifdef TX_DISABLE_INLINE
+
+UINT _tx_thread_interrupt_disable(VOID);
+VOID _tx_thread_interrupt_restore(UINT previous_posture);
+
+#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save;
+
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable();
+
+#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save);
+
+#else
+
+#define TX_INTERRUPT_SAVE_AREA __istate_t interrupt_save;
+#define TX_DISABLE {interrupt_save = __get_interrupt_state();__disable_interrupt();};
+#define TX_RESTORE {__set_interrupt_state(interrupt_save);};
+
+#define _tx_thread_system_return _tx_thread_system_return_inline
+
+static void _tx_thread_system_return_inline(void)
+{
+ TX_INTERRUPT_SAVE_AREA
+
+ TX_DISABLE
+
+ *((volatile UCHAR *)(0x872E0u)) = 1u;
+
+ TX_RESTORE
+}
+
+#endif
+
+
+#ifndef TX_THREAD_GET_SYSTEM_STATE
+
+extern volatile ULONG _tx_thread_system_state;
+#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | ((~__get_PSW_register()) & (1u << 17u)))
+#endif
+
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX RX/IAR Version 6.1.3 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+
+#endif
+
diff --git a/ports/rxv2/iar/readme_threadx.txt b/ports/rxv2/iar/readme_threadx.txt
new file mode 100644
index 00000000..0c0afd29
--- /dev/null
+++ b/ports/rxv2/iar/readme_threadx.txt
@@ -0,0 +1,163 @@
+ Microsoft's Azure RTOS ThreadX for Renesas RXv2
+
+ Using the IAR Tools
+
+
+1. Building the ThreadX run-time Library
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2.
+
+
+2. Demonstration System
+
+Please see the Samples repository on GitHub for the Azure RTOS demonstrations
+for the RXv2.
+
+
+3. System Initialization
+
+The system entry point using the IAR tools is at the label __iar_program_start.
+
+The vector area is setup in the file tx_initialize_low_level.s. This file is also
+responsible for setting up various system data structures, interrupt vectors, and
+the periodic timer interrupt. This file is also an ideal place add hardware
+initialization code.
+
+The ThreadX demonstration for the RXv2 utilizes CMT0 as a periodic timer interrupt
+source. The CMT0 interrupt is typically setup for 10ms periodic interrupts and the
+interrupt priority level is set to level 7. You may change any of the timer
+parameters as needed.
+
+In addition, _tx_initialize_low_level determines the first available address for use
+by the application, which is supplied as the sole input parameter to your application
+definition function, tx_application_define. The first available memory is determined
+by the location of the FREEMEM section so it should be placed AFTER all other RAM
+sections in your linker control file.
+
+
+4. Context Switch, Register Usage and Stack Frames
+
+The RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #17,
+to perform context switch. This ISR is thus reserved when using ThreadX and the SWINT
+should not be manipulated in any way by the application. The port will setup the
+interrupt within _tx_initialize_low_level and the compiler will automatically install
+the necessary interrupt vector. As such no additional initialization is necessary by the
+application.
+
+The following defines the saved context stack frame used by the ThreadX port. The
+state of the CPU registers at the time of a context switch is saved on the running
+thread's stack The top of the suspended thread's stack is pointed to by
+tx_thread_stack_ptr in the associated thread control block TX_THREAD.
+
+ Offset Interrupted Stack Frame
+
+ 0x00 1
+ 0x04 ACC0
+ 0x08 ACC1
+ 0x0C R6
+ 0x10 R7
+ 0x14 R8
+ 0x18 R9
+ 0x1C R10
+ 0x20 R11
+ 0x24 R12
+ 0x28 R13
+ 0x2C FPSW
+ 0x30 R14
+ 0x34 R15
+ 0x38 R3
+ 0x3C R4
+ 0x40 R5
+ 0x44 R1
+ 0x48 R2
+ 0x4C PC - return address
+ 0x50 PSW
+
+Note: By default IAR does not save the state of the accumulator registers ACC0 and ACC1
+when entering an ISR. This means that if the ISR uses any of the DSP instructions the
+content of those registers could be corrupted. Saving and restoring of the acummulators
+can be enabled by adding the --save_acc command line option.
+
+
+5. Improving Performance
+
+The distribution version of ThreadX is built without any compiler optimizations. This
+makes it easy to debug because you can trace or set breakpoints inside of ThreadX itself.
+Of course, this costs some performance. To make ThreadX run faster, you can change the
+ThreadX Library project to disable debug information and enable the desired optimizations.
+
+In addition, you can eliminate the ThreadX basic API error checking by compiling your
+application code with the symbol TX_DISABLE_ERROR_CHECKING defined before tx_api.h
+is included.
+
+
+6. Timer Processing
+
+Timer processign is performed by calling __tx_timer_interrupt(). This should usually be done
+from within the callback of a periodic timer with a period of 100Hz. In the sample projects
+a Renesas Fit CMT periodic timer module (rx_cmt) is used as the timer source.
+
+
+7. Interrupt Handling
+
+Interrupt handling is unaffected by the ThreadX port as such user interrupts can be
+written according to the toolchain's documentation. It is recommended not to use interrupt
+priority 15 as this is the priority of the context switch interrupt. However using interrupt
+priority 15 won't cause any negative side effectd but doing so may may slightly reduce
+performance. Please refer to the toolchain documentation for additional details on how to
+define interupt service routines.
+
+
+8. Execution Profiling
+
+The RX port adds support for the Execution Profiling Kit (EPK). The EPK consists
+of the files tx_execution_profile.c and tx_execution_profile.h. See the documentation
+of the EPK for generic usage details.
+
+To add the EPK to your RXv2 release make the following modifications:
+
+* Enable the following define for both the Threadx library and the application
+TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+
+* in tx_port.h, change around line 183
+change #define TX_THREAD_EXTENSION_3
+into #include "tx_execution_profile.h"
+
+* Setup CMT1 as a free running 16 bit timer.
+
+* In tx_execution_profile.h, change following around line 74:
+
+#ifdef TX_EXECUTION_64BIT_TIME
+typedef unsigned long long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \
+ unsigned long long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFFFFFFFFFFFFFF
+#else
+typedef unsigned long EXECUTION_TIME;
+#define TX_THREAD_EXTENSION_3 unsigned long tx_thread_execution_time_total; \
+ unsigned long tx_thread_execution_time_last_start;
+#define TX_EXECUTION_MAX_TIME_SOURCE 0xFFFF
+#endif
+
+/* Define basic constants for the execution profile kit. */
+
+#define TX_EXECUTION_TIME_SOURCE (EXECUTION_TIME) *((USHORT *) 0x8800A)
+
+Rebuild the Threadx library and the application.
+Refer to the EPK documentation how to interpret the results.
+
+
+9. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+12-31-2020 Initial ThreadX release for the RXv2using IAR tools, version 6.1.3
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
\ No newline at end of file
diff --git a/ports/rxv2/iar/src/tx_initialize_low_level.s b/ports/rxv2/iar/src/tx_initialize_low_level.s
new file mode 100644
index 00000000..49336a57
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_initialize_low_level.s
@@ -0,0 +1,99 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/** Initialize */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ extern __tx_initialize_unused_memory
+
+ section .text:CODE:ROOT
+
+;
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_initialize_low_level RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for any low-level processor */
+;/* initialization, including setting up interrupt vectors, setting */
+;/* up a periodic timer interrupt source, saving the system stack */
+;/* pointer for use in ISR processing later, and finding the first */
+;/* available RAM memory address for tx_application_define. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+ public __tx_initialize_low_level
+
+__tx_initialize_low_level:
+
+; /* Save the first available memory address. */
+; _tx_initialize_unused_memory = (VOID_PTR) &free_mem_start;
+;
+ MOV.L #__tx_free_memory_start, R1 ; Pickup unused memory address
+ MOV.L #__tx_initialize_unused_memory,R2
+ MOV.L R1,[R2] ; Save first free memory address
+
+; /* Set priority of SWINT to 1. */
+ MOV.L #0x87303, r1
+ MOV.L #1, r2
+ MOV.B r2, [r1]
+
+; /* Enable SWINT. */
+ MOV.L #0x87203, r1
+ MOV.B [r1], r2
+ OR #(1 << 3), r2
+ MOV.B r2, [r1]
+
+ RTS
+
+ section FREEMEM:DATA
+ public __tx_free_memory_start
+__tx_free_memory_start
+ DS32 4
+
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_context_restore.s b/ports/rxv2/iar/src/tx_thread_context_restore.s
new file mode 100644
index 00000000..491dae82
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_context_restore.s
@@ -0,0 +1,205 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ extern __tx_thread_system_state
+ extern __tx_thread_current_ptr
+ extern __tx_thread_preempt_disable
+ extern __tx_thread_execute_ptr
+ extern __tx_timer_time_slice
+ extern __tx_thread_schedule
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_restore RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function restores the interrupt context if it is processing a */
+;/* nested interrupt. If not, it returns to the interrupt thread if no */
+;/* preemption is necessary. Otherwise, if preemption is necessary or */
+;/* if no thread was running, the function returns to the scheduler. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling routine */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs Interrupt Service Routines */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+ public __tx_thread_context_restore
+
+__tx_thread_context_restore:
+;
+; /* Lockout interrupts. */
+
+ CLRPSW I ; disable interrupts
+
+; /* Determine if interrupts are nested. */
+; if (--_tx_thread_system_state)
+; {
+
+ MOV.L #__tx_thread_system_state, R1
+ MOV.L [R1], R2
+ SUB #1, R2
+ MOV.L R2,[R1]
+ BEQ __tx_thread_not_nested_restore
+
+;
+; /* Interrupts are nested. */
+;
+; /* Recover the saved registers from the interrupt stack
+; and return to the point of interrupt. */
+;
+__tx_thread_nested_restore:
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+; }
+
+__tx_thread_not_nested_restore:
+;
+; /* Determine if a thread was interrupted and no preemption is required. */
+; else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr)
+; || (_tx_thread_preempt_disable))
+; {
+
+ MOV.L #__tx_thread_current_ptr, R1 ; Pickup current thread ptr address
+ MOV.L [R1], R2
+ CMP #0, R2
+ BEQ __tx_thread_idle_system_restore
+
+ MOV.L #__tx_thread_preempt_disable, R3 ; pick up preempt disable flag
+ MOV.L [R3], R3
+ CMP #0, R3
+ BNE __tx_thread_no_preempt_restore ; if pre-empt disable flag set, we simply return to the original point of interrupt regardless
+
+ MOV.L #__tx_thread_execute_ptr, R3 ; (_tx_thread_current_ptr != _tx_thread_execute_ptr)
+ CMP [R3], R2
+ BNE __tx_thread_preempt_restore ; jump to pre-empt restoring
+;
+__tx_thread_no_preempt_restore:
+ SETPSW U ; user stack
+ POPC FPSW ; restore FPU status
+ POPM R14-R15 ; restore R14-R15
+ POPM R3-R5 ; restore R3-R5
+ POPM R1-R2 ; restore R1-R2
+ RTE ; return to point of interrupt, restore PSW including IPL
+
+; }
+; else
+; {
+
+__tx_thread_preempt_restore:
+
+; /* Save the remaining time-slice and disable it. */
+; if (_tx_timer_time_slice)
+; {
+
+ MOV.L #__tx_timer_time_slice, R3 ; Pickup time-slice address
+ MOV.L [R3],R4 ; Pickup actual time-slice
+ CMP #0, R4
+ BEQ __tx_thread_dont_save_ts ; no time slice to save
+;
+; _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+; _tx_timer_time_slice = 0;
+;
+ MOV.L R4,24[R2] ; Save thread's time slice
+ MOV.L #0,R4 ; Clear value
+ MOV.L R4,[R3] ; Disable global time slice flag
+; }
+__tx_thread_dont_save_ts:
+;
+; /* Now store the remaining registers! */
+
+ SETPSW U ; user stack
+ PUSHM R6-R13
+
+ MVFACGU #0, A1, R4 ; Save accumulators.
+ MVFACHI #0, A1, R5
+ MVFACLO #0, A1, R6
+ PUSHM R4-R6
+ MVFACGU #0, A0, R4
+ MVFACHI #0, A0, R5
+ MVFACLO #0, A0, R6
+ PUSHM R4-R6
+
+ MOV.L #1, R3 ; indicate interrupt stack frame
+ PUSH.L R3
+
+;
+; /* Clear the current task pointer. */
+; _tx_thread_current_ptr = TX_NULL;
+; R1 -> _tx_thread_current_ptr
+; R2 -> *_tx_thread_current_ptr
+
+ MOV.L R0,8[R2] ; Save thread's stack pointer in thread control block
+ MOV.L #0,R2 ; Build NULL value
+ MOV.L R2,[R1] ; Set current thread to NULL
+
+; /* Return to the scheduler. */
+; _tx_thread_schedule();
+
+__tx_thread_idle_system_restore:
+ MVTC #0, PSW ; reset interrupt priority level to 0
+ BRA __tx_thread_schedule ; jump to scheduler
+; }
+;
+;}
+;
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_context_save.s b/ports/rxv2/iar/src/tx_thread_context_save.s
new file mode 100644
index 00000000..218f65cd
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_context_save.s
@@ -0,0 +1,170 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+ extern __tx_thread_system_state
+ extern __tx_thread_current_ptr
+
+ section .text:CODE:ROOT
+ ;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_context_save RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function saves the context of an executing thread in the */
+;/* beginning of interrupt processing. The function also ensures that */
+;/* the system stack is used upon return to the calling ISR. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ISRs */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_context_save(VOID)
+;{
+ public __tx_thread_context_save
+
+__tx_thread_context_save:
+;
+; /* Upon entry to this routine, it is assumed that interrupts are locked
+; out and the (interrupt) stack frame looks like the following:
+;
+; (lower address) SP -> [return address of this call]
+; SP+4 -> Saved R1
+; SP+8 -> Saved R2
+; SP+12-> Interrupted PC
+; SP+16-> Interrupted PSW
+;
+; /* Check for a nested interrupt condition. */
+; if (_tx_thread_system_state++)
+; {
+;
+
+ MOV.L #__tx_thread_system_state, R1 ; pick up address of system state
+ MOV.L [R1], R2 ; pick up system state
+ CMP #0, R2 ; 0 -> no nesting
+ BEQ __tx_thread_not_nested_save
+;
+; /* Nested interrupt condition. */
+;
+ ADD #1, r2 ; _tx_thread_system_state++
+ MOV.L r2, [r1]
+
+;
+; /* Save the rest of the scratch registers on the interrupt stack and return to the
+; calling ISR. */
+ POP R1 ; recuperate return address from stack
+ PUSHM R3-R5
+ PUSHM R14-R15
+ PUSHC FPSW ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
+ JMP R1 ; return address was preserved in R1
+
+;
+__tx_thread_not_nested_save:
+; }
+;
+; /* Otherwise, not nested, check to see if a thread was running. */
+; else if (_tx_thread_current_ptr)
+; {
+;
+ ADD #1, R2 ; _tx_thread_system_state++
+ MOV.L R2, [R1]
+
+ MOV.L #__tx_thread_current_ptr, R2 ; Pickup current thread pointer
+ MOV.L [R2], R2
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_idle_system_save ; Yes, idle system is running - idle restore
+;
+; /* Move stack frame over to the current threads stack. */
+; /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW) */
+;
+ MVFC USP, R1 ; pick up user stack pointer
+ MOV.L 16[R0], R2
+ MOV.L R2, [-R1] ; save PSW on thread stack
+ MOV.L 12[R0], R2
+ MOV.L R2, [-R1] ; save PC on thread stack
+ MOV.L 8[R0], R2
+ MOV.L R2, [-R1] ; save R2 on thread stack
+ MOV.L 4[R0], R2
+ MOV.L R2, [-R1] ; save R1 on thread stack
+ MOV.L R5, [-R1] ; save R5 on thread stack
+ MOV.L R4, [-R1] ; save R4 on thread stack
+ MOV.L R3, [-R1] ; save R3 on thread stack
+ MOV.L R15, [-R1] ; save R15 on thread stack
+ MOV.L R14, [-R1] ; save R14 on thread stack
+ MVFC FPSW, R3
+ MOV.L R3, [-R1] ; save FPSW on thread stack
+
+ POP R2 ; pick up return address from interrupt stack
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom
+ MVTC R1, USP ; set user/thread stack pointer
+ JMP R2 ; return to ISR
+
+; }
+; else
+; {
+;
+__tx_thread_idle_system_save:
+;
+; /* Interrupt occurred in the scheduling loop. */
+;
+ POP R1 ; pick up return address
+ ADD #16, R0, R0 ; correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
+ JMP R1 ; return to caller
+;
+; }
+;}
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_interrupt_control.s b/ports/rxv2/iar/src/tx_thread_interrupt_control.s
new file mode 100644
index 00000000..bd8474df
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_interrupt_control.s
@@ -0,0 +1,93 @@
+;/**************************************************************************/
+;/* */
+;/* 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"
+;
+ section .text:CODE:ROOT
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_interrupt_control RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is responsible for changing the interrupt lockout */
+;/* posture of the system. */
+;/* */
+;/* INPUT */
+;/* */
+;/* new_posture New interrupt lockout posture */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* old_posture Old interrupt lockout posture */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* Application Code */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;UINT _tx_thread_interrupt_control(UINT new_posture)
+;{
+ public __tx_thread_interrupt_control
+__tx_thread_interrupt_control:
+;
+; /* Pickup current interrupt lockout posture. */
+;
+
+ MVFC PSW, R2 ; Save PSW to R2
+ MOV.L R2, R3 ; Make a copy of PSW in r3
+
+;
+; /* Apply the new interrupt posture. */
+;
+
+ BTST #16, R1 ; test I bit of PSW of "new posture"
+ BMNE #16, R2 ; conditionally set I bit of intermediate posture
+
+ MVTC R2, PSW ; save intermediate posture to PSW
+
+ MOV.L R3,R1 ; Get original SR
+ RTS ; Return to caller
+;}
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_schedule.s b/ports/rxv2/iar/src/tx_thread_schedule.s
new file mode 100644
index 00000000..9de14be1
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_schedule.s
@@ -0,0 +1,179 @@
+;/**************************************************************************/
+;/* */
+;/* 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_timer.h"
+;
+;
+ extern __tx_thread_execute_ptr
+ extern __tx_thread_current_ptr
+ extern __tx_timer_time_slice
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_schedule RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function waits for a thread control block pointer to appear in */
+;/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+;/* in the variable, the corresponding thread is resumed. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_initialize_kernel_enter ThreadX entry function */
+;/* _tx_thread_system_return Return to system from thread */
+;/* _tx_thread_context_restore Restore thread's context */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+;VOID _tx_thread_schedule(VOID)
+;{
+ public __tx_thread_schedule
+
+__tx_thread_schedule:
+;
+; /* Enable interrupts. */
+;
+ SETPSW I
+;
+; /* Wait for a thread to execute. */
+; do
+; {
+ MOV.L #__tx_thread_execute_ptr, R1 ; Address of thread to executer ptr
+__tx_thread_schedule_loop:
+ MOV.L [R1],R2 ; Pickup next thread to execute
+ CMP #0,R2 ; Is it NULL?
+ BEQ __tx_thread_schedule_loop ; Yes, idle system, keep checking
+;
+; }
+; while(_tx_thread_execute_ptr == TX_NULL);
+;
+; /* Yes! We have a thread to execute. Lockout interrupts and
+; transfer control to it. */
+;
+ CLRPSW I ; disable interrupts
+;
+; /* Setup the current thread pointer. */
+; _tx_thread_current_ptr = _tx_thread_execute_ptr;
+;
+ MOV.L #__tx_thread_current_ptr, R3
+ MOV.L R2,[R3] ; Setup current thread pointer
+;
+; /* Increment the run count for this thread. */
+; _tx_thread_current_ptr -> tx_thread_run_count++;
+;
+ MOV.L 4[R2],R3 ; Pickup run count
+ ADD #1,R3 ; Increment run counter
+ MOV.L R3,4[R2] ; Store it back in control block
+;
+; /* Setup time-slice, if present. */
+; _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+;
+ MOV.L 24[R2],R3 ; Pickup thread time-slice
+ MOV.L #__tx_timer_time_slice,R4 ; Pickup pointer to time-slice
+ MOV.L R3, [R4] ; Setup time-slice
+;
+; /* Switch to the thread's stack. */
+; SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ SETPSW U ; user stack mode
+ MOV.L 8[R2],R0 ; Pickup stack pointer
+;
+; /* Determine if an interrupt frame or a synchronous task suspension frame
+; is present. */
+;
+ POP R1 ; Pickup stack type
+ CMP #1, R1 ; Is it an interrupt stack?
+ BNE __tx_thread_synch_return ; No, a synchronous return frame is present.
+
+ POPM R1-R3 ; Restore accumulators.
+ MVTACLO R3, A0
+ MVTACHI R2, A0
+ MVTACGU R1, A0
+ POPM R1-R3
+ MVTACLO R3, A1
+ MVTACHI R2, A1
+ MVTACGU R1, A1
+
+ POPM R6-R13 ; Recover interrupt stack frame
+ POPC FPSW
+ POPM R14-R15
+ POPM R3-R5
+ POPM R1-R2
+ RTE ; return to point of interrupt, this restores PC and PSW
+
+__tx_thread_synch_return:
+ POPC PSW
+ POPM R6-R13 ; Recover solicited stack frame
+ RTS
+;
+;}
+
+ extern __tx_thread_context_save
+ extern __tx_thread_context_restore
+
+; Software triggered interrupt used to perform context switches.
+; The priority of this interrupt is set to the lowest priority within
+; tx_initialize_low_level() and triggered by ThreadX when calling
+; _tx_thread_system_return().
+ public ___interrupt_27
+___interrupt_27:
+
+ PUSHM R1-R2
+
+ BSR __tx_thread_context_save
+
+ BRA __tx_thread_context_restore
+
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_stack_build.s b/ports/rxv2/iar/src/tx_thread_stack_build.s
new file mode 100644
index 00000000..688f0bc8
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_stack_build.s
@@ -0,0 +1,147 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+;
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_stack_build RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function builds a stack frame on the supplied thread's stack. */
+;/* The stack frame results in a fake interrupt return to the supplied */
+;/* function pointer. */
+;/* */
+;/* INPUT */
+;/* */
+;/* thread_ptr Pointer to thread control blk */
+;/* function_ptr Pointer to return function */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* None */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* _tx_thread_create Create thread service */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_thread_stack_build
+
+__tx_thread_stack_build:
+;
+;
+; /* Build an interrupt frame. The form of the fake interrupt stack
+; on the Renesas RX should look like the following after it is built:
+;
+; Stack Top: 1 Interrupt stack frame type
+; ACC0
+; ACC1
+; R6
+; R7
+; R8
+; R9
+; R10
+; R11
+; R12
+; R13
+; FPSW
+; R14
+; R15
+; R3
+; R4
+; R5
+; R1
+; R2
+; PC
+; PSW
+
+;
+; Stack Bottom: (higher memory address) */
+;
+ MOV.L 16[R1],R3 ; Pickup end of stack area
+ BCLR #0, R3 ; mask for 4-byte alignment
+ BCLR #1, R3
+;
+; /* Build the stack frame. */
+;
+ MOV.L #30000h, R4
+ MOV.L R4, [-R3] ; initial PSW (SVC mode, U flag set)
+ MOV.L R2, [-R3] ; initial PC
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R2 ...
+ MOV.L R4,[-R3] ; initial R1 ...
+ MOV.L R4,[-R3] ; initial R5 ...
+ MOV.L R4,[-R3] ; initial R4 ...
+ MOV.L R4,[-R3] ; initial R3 ...
+ MOV.L R4,[-R3] ; initial R15 ...
+ MOV.L R4,[-R3] ; initial R14 ...
+ MVFC FPSW, r4
+ MOV.L R4, [-R3] ; initial FPSW
+ MOV.L #0, R4
+ MOV.L R4,[-R3] ; initial R13 ...
+ MOV.L R4,[-R3] ; initial R12 ...
+ MOV.L R4,[-R3] ; initial R11 ...
+ MOV.L R4,[-R3] ; initial R10 ...
+ MOV.L R4,[-R3] ; initial R9 ...
+ MOV.L R4,[-R3] ; initial R8 ...
+ MOV.L R4,[-R3] ; initial R7 ...
+ MOV.L R4,[-R3] ; initial R6 ...
+
+ MOV.L R4,[-R3] ; Accumulator 1
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L R4,[-R3] ; Accumulator 0
+ MOV.L R4,[-R3]
+ MOV.L R4,[-R3]
+
+ MOV.L #1, R4
+ MOV.L R4,[-R3] ; indicate interrupt stack frame
+; /* Setup stack pointer. */
+; thread_ptr -> tx_thread_stack_ptr = R1;
+ MOV.L R3, 8[R1]
+ ; store initial SP in thread control block
+ RTS
+
+;}
+
+ END
diff --git a/ports/rxv2/iar/src/tx_thread_system_return.s b/ports/rxv2/iar/src/tx_thread_system_return.s
new file mode 100644
index 00000000..808e345e
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_thread_system_return.s
@@ -0,0 +1,74 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ section .text:CODE:ROOT
+
+ ;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_thread_system_return RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function is target processor specific. It is used to transfer */
+;/* control from a thread back to the system. Only a minimal context */
+;/* is saved since the compiler assumes temp registers are going to get */
+;/* slicked by a function call anyway. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_schedule Thread scheduling loop */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* ThreadX components */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_thread_system_return
+
+__tx_thread_system_return:
+
+ BRA __tx_thread_system_return
+
+ RTS
+
+ END
diff --git a/ports/rxv2/iar/src/tx_timer_interrupt.s b/ports/rxv2/iar/src/tx_timer_interrupt.s
new file mode 100644
index 00000000..645f73b4
--- /dev/null
+++ b/ports/rxv2/iar/src/tx_timer_interrupt.s
@@ -0,0 +1,235 @@
+;/**************************************************************************/
+;/* */
+;/* 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 */
+;/** */
+;/**************************************************************************/
+;/**************************************************************************/
+
+ extern __tx_timer_expiration_process
+ extern __tx_timer_system_clock
+ extern __tx_timer_expired_time_slice
+ extern __tx_timer_current_ptr
+ extern __tx_timer_expired
+ extern __tx_timer_list_start
+ extern __tx_timer_time_slice
+ extern __tx_timer_list_end
+ extern __tx_thread_time_slice
+
+ section .text:CODE:ROOT
+
+;/**************************************************************************/
+;/* */
+;/* FUNCTION RELEASE */
+;/* */
+;/* _tx_timer_interrupt RX/IAR */
+;/* 6.1.3 */
+;/* AUTHOR */
+;/* */
+;/* William E. Lamie, Microsoft Corporation */
+;/* */
+;/* DESCRIPTION */
+;/* */
+;/* This function processes the hardware timer interrupt. This */
+;/* processing includes incrementing the system clock and checking for */
+;/* time slice and/or timer expiration. If either is found, the */
+;/* interrupt context save/restore functions are called along with the */
+;/* expiration functions. */
+;/* */
+;/* INPUT */
+;/* */
+;/* None */
+;/* */
+;/* OUTPUT */
+;/* */
+;/* None */
+;/* */
+;/* CALLS */
+;/* */
+;/* _tx_thread_context_save Save interrupted context */
+;/* _tx_timer_expiration_process Timer expiration processing */
+;/* _tx_thread_time_slice Time slice interrupted thread */
+;/* _tx_thread_context_restore Restore interrupted context */
+;/* */
+;/* CALLED BY */
+;/* */
+;/* interrupt vector */
+;/* */
+;/* RELEASE HISTORY */
+;/* */
+;/* DATE NAME DESCRIPTION */
+;/* */
+;/* 12-31-2020 William E. Lamie Initial Version 6.1.3 */
+;/* */
+;/**************************************************************************/
+
+ public __tx_timer_interrupt
+__tx_timer_interrupt:
+;
+; /* Upon entry to this routine, it is assumed that all interrupts are locked
+; out and the stack looks like the following:
+; SP+4 -> Interrupted PC
+; SP+8-> Interrupted SR
+; */
+;
+; /* Increment the system clock. */
+; _tx_timer_system_clock++;
+;
+ PUSHM R14-R15
+ PUSHM R1-R5
+
+ MOV.L #__tx_timer_system_clock, R1 ; Pickup address of system clock
+ MOV.L [R1], R2 ; Pickup system clock
+ ADD #1, R2 ; Increment system clock
+ MOV.L R2,[R1] ; Store new system clock
+;
+; /* Test for time-slice expiration. */
+; if (_tx_timer_time_slice)
+; {
+;
+ MOV.L #__tx_timer_time_slice, R1 ; Pickup address of time slice
+ MOV.L [R1], R2 ; Pickup the current time slice
+ CMP #0, R2 ; Is a time slice active?
+ BEQ __tx_timer_no_time_slice ; No, skip timer slice processing
+;
+; /* Decrement the time_slice. */
+; _tx_timer_time_slice--;
+;
+ SUB #1, R2 ; Decrement the time-slice
+ MOV.L R2, [R1] ; Store time-slice
+;
+; /* Check for expiration. */
+; if (__tx_timer_time_slice == 0)
+;
+ CMP #0, R2 ; Has it expired?
+ BNE __tx_timer_no_time_slice ; No, time-slice has not expired
+;
+; /* Set the time-slice expired flag. */
+; _tx_timer_expired_time_slice = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup address of expired time-slice
+ MOV.L #1, R2 ; Build expired value
+ MOV.L R2, [R1] ; Set expired time slice variable
+; }
+;
+__tx_timer_no_time_slice:
+;
+; /* Test for timer expiration. */
+; if (*_tx_timer_current_ptr)
+; {
+;
+ MOV.L #__tx_timer_current_ptr, R1 ; Pickup address of current timer ptr
+ MOV.L [R1], R2 ; Pickup current pointer
+ MOV.L [R2+], R1 ; pickup timer list entry, _tx_timer_current_ptr++
+ CMP #0, R1 ; Is timer pointer NULL?
+ BEQ __tx_timer_no_timer ; Yes, no timer has expired
+
+;
+; /* Set expiration flag. */
+; _tx_timer_expired = TX_TRUE;
+;
+ MOV.L #__tx_timer_expired,R2 ; Build address of expired flag
+ MOV.L #1, R1 ; Build expired value
+ MOV.L R1, [R2]
+ BRA __tx_timer_done ; Finished with timer processing
+;
+; }
+; else
+; {
+__tx_timer_no_timer:
+;
+; /* No timer expired, increment the timer pointer. */
+; _tx_timer_current_ptr++;
+;
+; /* R2 already contains __tx_timer_current_ptr++ */
+;
+; /* Check for wrap-around. */
+; if (_tx_timer_current_ptr == _tx_timer_list_end)
+;
+ MOV.L #__tx_timer_list_end, R1 ; Pickup the timer list end ptr
+ MOV.L [R1], R1 ; Pickup actual timer list end
+ CMP R1, R2 ; Are we at list end?
+ BNE __tx_timer_skip_wrap ; No, don't move pointer to the
+ ; top of the list
+;
+; /* Wrap to beginning of list. */
+; _tx_timer_current_ptr = _tx_timer_list_start;
+;
+ MOV.L #__tx_timer_list_start, R2 ; Pickup the timer list start ptr
+ MOV.L [R2], R2 ; Pickup the start of the list
+; }
+;
+__tx_timer_skip_wrap:
+ MOV.L #__tx_timer_current_ptr,R1
+ MOV.L R2, [R1] ; store in updated pointer in _tx_timer_current_ptr
+
+__tx_timer_done:
+;
+; /* See if anything has expired. */
+; if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup expired time slice addr
+ MOV.L [R1], R1 ; Pickup expired time slice
+ MOV.L #__tx_timer_expired, R2 ; Pickup expired timer flag address
+ MOV.L [R2], R2 ; Pickup actual flag
+ OR R1, R2 ; Or flags together
+ BEQ __tx_timer_nothing_expired ; If Z set, nothing has expired
+
+__tx_something_expired:
+; /* Did a timer expire? */
+; if (_tx_timer_expired)
+; {
+ MOV.L #__tx_timer_expired,R1 ; Pickup expired flag address
+ MOV.L [R1], R1 ; Pickup expired flag
+ CMP #0,R1 ; Is the expired timer flag set?
+ BEQ __tx_timer_dont_activate ; No, skip timer activation
+;
+; /* Process timer expiration. */
+; _tx_timer_expiration_process();
+;
+ BSR __tx_timer_expiration_process ; Call the timer expiration handling routine
+;
+; }
+__tx_timer_dont_activate:
+;
+; /* Did time slice expire? */
+; if (_tx_timer_expired_time_slice)
+; {
+;
+ MOV.L #__tx_timer_expired_time_slice, R1 ; Pickup time-slice expired flag addr
+ MOV.L [R1], R1 ; Pickup actual flag
+ CMP #0,R1 ; Has time-slice expired?
+ BEQ __tx_timer_not_ts_expiration ; No, skip time-slice expiration
+;
+; /* Time slice interrupted thread. */
+; _tx_thread_time_slice();
+
+ BSR __tx_thread_time_slice ; Call time-slice processing
+; }
+;
+__tx_timer_not_ts_expiration:
+
+__tx_timer_nothing_expired:
+
+ POPM R1-R5
+ POPM R14-R15
+;
+ RTS ; return to point of interrupt
+;
+;}
+ END
\ No newline at end of file
diff --git a/ports/xtensa/xcc/CMakeLists.txt b/ports/xtensa/xcc/CMakeLists.txt
new file mode 100644
index 00000000..31768e58
--- /dev/null
+++ b/ports/xtensa/xcc/CMakeLists.txt
@@ -0,0 +1,36 @@
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_clib_lock.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_xtensa_stack_error_handler.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_context.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_coproc_handler.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_init.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_intr_asm.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_intr.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_intr_wrapper.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_overlay_os_hook.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_vectors.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/xtensa_vectors_xea3.S
+
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
+
+set_source_files_properties(${CMAKE_CURRENT_LIST_DIR}/src/xtensa_vectors_xea3.S
+ TARGET_DIRECTORY ${PROJECT_NAME}
+ PROPERTIES COMPILE_OPTIONS "-mtext-section-literals")
+
diff --git a/ports/xtensa/xcc/example_build/demo_threadx.c b/ports/xtensa/xcc/example_build/demo_threadx.c
new file mode 100644
index 00000000..5bec9cc8
--- /dev/null
+++ b/ports/xtensa/xcc/example_build/demo_threadx.c
@@ -0,0 +1,377 @@
+/* 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
+#include
+
+#include "tx_api.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()
+{
+
+ /* 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;
+
+ /* Print something to show we are making progress. This should use the print
+ function from libxtutil which is thread-safe. */
+ printf("%u %u %u\n", thread_0_counter, thread_1_counter, thread_2_counter);
+ }
+}
+
+
+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/xtensa/xcc/inc/tx_api_asm.h b/ports/xtensa/xcc/inc/tx_api_asm.h
new file mode 100644
index 00000000..1840ffce
--- /dev/null
+++ b/ports/xtensa/xcc/inc/tx_api_asm.h
@@ -0,0 +1,67 @@
+
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains macro constants for ThreadX API structures */
+/* and enums that need to be used in assembly coded port sources. */
+/* Most of these constants are derived from definitions in tx_api.h. */
+/* Only the constants that are needed are included here to reduce */
+/* the maintenance required when the structures or enums change. */
+/* Structure offsets depend on the compiler, so are tools-specific, */
+/* which usually means port-specific since a compiler's struct */
+/* packing rules depend on properties of the target architecture. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_API_ASM_H
+#define TX_API_ASM_H
+
+#include "tx_port.h"
+
+/* API input parameters and general constants. */
+
+#define TX_TRUE 1
+#define TX_FALSE 0
+#define TX_NULL 0
+
+/* ThreadX thread control block structure. */
+// typedef struct TX_THREAD_STRUCT
+// {
+
+#define tx_thread_run_count 0x04
+#define tx_thread_stack_ptr 0x08
+#define tx_thread_stack_end 0x10
+#define tx_thread_time_slice 0x18
+#define tx_thread_new_time_slice 0x1C
+#define tx_thread_solicited 0x28
+
+#ifdef TX_THREAD_SAFE_CLIB
+ #define tx_real_thread_entry 0x2C
+ #define tx_thread_clib_ptr 0x30
+ #define tx_thread_cp_state 0x34
+#else
+ #define tx_thread_cp_state 0x2C
+#endif
+
+// }
+
+#endif /* TX_API_ASM_H */
+
diff --git a/ports/xtensa/xcc/inc/tx_port.h b/ports/xtensa/xcc/inc/tx_port.h
new file mode 100644
index 00000000..9438a7c8
--- /dev/null
+++ b/ports/xtensa/xcc/inc/tx_port.h
@@ -0,0 +1,479 @@
+
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains data type definitions that make the ThreadX */
+/* real-time kernel function identically on a variety of different */
+/* processor architectures. For example, the size or number of bits */
+/* in an "int" data type vary between microprocessor architectures and */
+/* even C compilers for the same microprocessor. ThreadX does not */
+/* directly use native C data types. Instead, ThreadX creates its */
+/* own special types that can be mapped to actual data types by this */
+/* file to guarantee consistency in the interface and functionality. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_PORT_H
+#define TX_PORT_H
+
+/* Determine if the optional ThreadX user define file should be used. */
+
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+/* Comment this out to disable thread-safe C library support. */
+#define TX_THREAD_SAFE_CLIB 1
+
+/* Include the glue to Xtensa-generic parts of this ThreadX port. */
+#include "xtensa_rtos.h"
+
+/* Parts of this file should not been seen by assembler sources. */
+#ifndef __ASSEMBLER__
+
+/* Some generic C sources call memset() and need this (else compiler warns).
+ Until the generic sources take care of this, do it here. */
+
+#include
+
+
+/* Define compiler library include files and library-specific macros. */
+
+/*
+ Thread-safety support for the supported C libraries. At this time
+ only the newlib and Xtensa C libraries are supported.
+
+ The C library reent structure can be quite large so it is placed
+ at the end of TX_THREAD, and a pointer to it is defined near the
+ beginning of TX_THREAD where assembly code can easily get to it
+ at a fixed offset.
+*/
+
+#ifdef TX_THREAD_SAFE_CLIB
+struct TX_THREAD_STRUCT;
+
+extern char *_tx_clib_heap_start, *_tx_clib_heap_end;
+extern void _tx_clib_reent_init (struct TX_THREAD_STRUCT *thread_ptr);
+extern void _tx_clib_reent_cleanup (struct TX_THREAD_STRUCT *thread_ptr, int partial);
+extern void _tx_clib_thread_setup(struct TX_THREAD_STRUCT *thread_ptr);
+
+#include
+
+#define TX_CLIB_THREAD_EXTENSION \
+ VOID (*tx_real_thread_entry)(ULONG id); /* Actual entry point */ \
+ struct _reent * tx_thread_clib_ptr; /* C lib reentrancy ptr */
+#define TX_CLIB_THREAD_EXTENSION_END \
+ struct _reent tx_thread_clib_reent; /* C lib reentrancy struct */
+#define TX_CLIB_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_CLIB_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_CLIB_THREAD_EXIT_EXTENSION(thread_ptr)
+#define TX_THREAD_CLIB_EXTENSION(thread_ptr) \
+ _tx_clib_thread_setup(thread_ptr);
+#else
+#define TX_CLIB_THREAD_EXTENSION
+#define TX_CLIB_THREAD_EXTENSION_END
+#define TX_CLIB_THREAD_CREATE_EXTENSION(thread_ptr)
+#define TX_CLIB_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_CLIB_THREAD_EXIT_EXTENSION(thread_ptr)
+#define TX_THREAD_CLIB_EXTENSION(thread_ptr)
+#endif
+
+
+/* Define ThreadX basic types for this port. */
+
+#define VOID void
+typedef char CHAR;
+typedef unsigned char UCHAR;
+typedef int INT;
+typedef unsigned int UINT;
+typedef long LONG;
+typedef unsigned long ULONG;
+typedef short SHORT;
+typedef unsigned short USHORT;
+
+
+#endif /* #ifndef __ASSEMBLER__ */
+
+
+/* Define the priority levels for ThreadX. Legal values range
+ from 32 to 1024 and MUST be evenly divisible by 32. */
+
+#ifndef TX_MAX_PRIORITIES
+#define TX_MAX_PRIORITIES 32
+#endif
+
+
+/*
+ Define the minimum stack size for a thread on this processor.
+ If the size supplied during thread creation is less than TX_MINIMUM_STACK,
+ the thread create call will return an error. The minimum allows for a
+ thread whose entry function makes no calls and needs no local frame.
+ TX_MINIMUM_STACK_BASIC allows the entry function to at least call
+ tx_thread_relinquish(). An extra 0x10 bytes is allowed in all cases to
+ allow for stack pointer alignment to 16 bytes. There is an additional premium
+ for the stack checking functionality of TX_ENABLE_STACK_CHECKING.
+ In Xtensa, all these amounts depend on the function call ABI used by the
+ configuration (in general, Call0 ABI needs about 0x20 bytes less stack space
+ per function call frame). These amounts assume no compiler optimization (-O0).
+ Optimization usually requires less stack.
+
+ TX_MINIMUM_STACK_BASIC is a MINIMUM for threads that call tx_thread_relinquish()
+ only. Threads that do more, and in particular call C library functions such as
+ printf(), need much more stack space and it is up to the application developer
+ to determine how much.
+*/
+
+#ifdef __XTENSA_CALL0_ABI__
+ /* Call0 ABI */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK (XT_STK_FRMSZ + 0x10)
+#endif
+#ifdef TX_ENABLE_STACK_CHECKING
+#define TX_STACK_CHECK_PREMIUM 0x30
+#else
+#define TX_STACK_CHECK_PREMIUM 0
+#endif
+#ifndef TX_MINIMUM_STACK_BASIC
+#define TX_MINIMUM_STACK_BASIC (XT_STK_FRMSZ + 0x70 + TX_STACK_CHECK_PREMIUM)
+#endif
+
+#else /* Windowed ABI */
+
+#ifndef TX_MINIMUM_STACK
+#define TX_MINIMUM_STACK (XT_STK_FRMSZ + 0x20)
+#endif
+#ifdef TX_ENABLE_STACK_CHECKING
+#define TX_STACK_CHECK_PREMIUM 0x50
+#else
+#define TX_STACK_CHECK_PREMIUM 0
+#endif
+#ifndef TX_MINIMUM_STACK_BASIC
+#define TX_MINIMUM_STACK_BASIC (XT_STK_FRMSZ + 0x100 + TX_STACK_CHECK_PREMIUM)
+#endif
+
+#endif
+
+/*
+ Minimum stack size for the ThreadX system stack on this processor.
+ This is just a useful starting point for an application, it is not
+ checked by ThreadX. The minimum system stack size allows for the
+ possible depth of interrupt nesting (XCHAL_EXCM_LEVEL-1 interrupt
+ stack frames and XCHAL_EXCM_LEVEL interrupt handlers including timer),
+ assuming very basic interrupt handlers (allows 1 call12). It needs to
+ be increased to support the application's real interrupt handlers (and
+ timer interrupt if TX_TIMER_PROCESS_IN_ISR). The system stack is located
+ where the stack pointer is inside tx_kernel_enter() which is usually from
+ main(), and so is determined by the development tools. It grows downward
+ toward the first available memory pointer passed to tx_application_define().
+ An application should allow sufficient space for the system stack.
+
+ For XEA3, allow a minimum of XCHAL_NUM_INTLEVELS nested interrupts. The stack
+ frames are minimal-sized and may need to be increased to support real applications.
+*/
+
+#if XCHAL_HAVE_XEA3
+#define TX_SYSTEM_STACK_MINIMUM (XCHAL_NUM_INTLEVELS * 0x40)
+#ifndef TX_SYSTEM_STACK_SIZE
+#if TX_SYSTEM_STACK_MINIMUM > 2048
+#define TX_SYSTEM_STACK_SIZE TX_SYSTEM_STACK_MINIMUM
+#else
+#define TX_SYSTEM_STACK_SIZE 2048
+#endif
+#endif
+#else
+#define TX_SYSTEM_STACK_MINIMUM (((XCHAL_EXCM_LEVEL-1) * (0x40 + XT_STK_FRMSZ)) + 0x40)
+#ifndef TX_SYSTEM_STACK_SIZE
+#define TX_SYSTEM_STACK_SIZE 4096
+#endif
+#endif
+
+/*
+ Define the system timer thread's default stack size and priority.
+ These are only applicable if TX_TIMER_PROCESS_IN_ISR is not defined.
+*/
+
+#ifndef TX_TIMER_THREAD_STACK_SIZE
+#ifdef __XTENSA_CALL0_ABI__
+#define TX_TIMER_THREAD_STACK_SIZE (TX_MINIMUM_STACK_BASIC + 0x100)
+#else
+#define TX_TIMER_THREAD_STACK_SIZE (TX_MINIMUM_STACK_BASIC + 0x200)
+#endif
+#endif
+
+
+/* Parts of this file should not been seen by assembler sources. */
+#ifndef __ASSEMBLER__
+
+
+#ifndef TX_TIMER_THREAD_PRIORITY
+#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */
+#endif
+
+
+/* Define various constants for the ThreadX Xtensa port. */
+
+#if XCHAL_HAVE_XEA3
+#define TX_INT_DISABLE 0x8 /* Disable interrupts value */
+#define TX_INT_ENABLE 0x0 /* Enable interrupt value */
+#else
+#define TX_INT_DISABLE XCHAL_EXCM_LEVEL /* Disable interrupts value */
+#define TX_INT_ENABLE 0x0 /* Enable interrupt value */
+#endif
+
+
+/*
+ Define the clock source for trace event entry time stamp. The following
+ two item are port specific. For example, if the time source is at the
+ address 0x0a800024 and is 16-bits in size, the clock source constants
+ would be:
+
+ #define TX_TRACE_TIME_SOURCE *((ULONG *) 0x0a800024)
+ #define TX_TRACE_TIME_MASK 0x0000FFFFUL
+*/
+
+#ifndef TX_TRACE_TIME_SOURCE
+#define TX_TRACE_TIME_SOURCE ++_tx_trace_simulated_time
+#endif
+#ifndef TX_TRACE_TIME_MASK
+#define TX_TRACE_TIME_MASK 0xFFFFFFFFUL
+#endif
+
+
+/*
+ Define the port specific options for the _tx_build_options variable.
+ This variable indicates how the ThreadX library was built.
+*/
+
+#if defined(XT_SIMULATOR) || !defined(XT_BOARD)
+#define TX_XT_OPT_SIMULATOR (1UL << 0)
+#else
+#define TX_XT_OPT_SIMULATOR 0
+#endif
+
+#if defined(XT_BOARD)
+#define TX_XT_OPT_BOARD (1UL << 1)
+#else
+#define TX_XT_OPT_BOARD 0
+#endif
+
+#if defined(XT_INTEXC_HOOKS)
+#define TX_XT_OPT_INTEXC_HOOKS (1UL << 2)
+#else
+#define TX_XT_OPT_INTEXC_HOOKS 0
+#endif
+
+#if defined(TX_THREAD_SAFE_CLIB)
+#define TX_XT_OPT_CLIB (1UL << 3)
+#else
+#define TX_XT_OPT_CLIB 0
+#endif
+
+#define TX_PORT_SPECIFIC_BUILD_OPTIONS (TX_XT_OPT_SIMULATOR | TX_XT_OPT_BOARD \
+ | TX_XT_OPT_INTEXC_HOOKS | TX_XT_OPT_CLIB)
+
+
+/*
+ Define the in-line initialization constant so that modules with in-line
+ initialization capabilities can prevent their initialization from being
+ a function call.
+*/
+
+#define TX_INLINE_INITIALIZATION
+
+
+/*
+ Determine whether or not stack checking is enabled. By default, ThreadX
+ stack checking is disabled. When the following is defined, ThreadX thread
+ stack checking is enabled. If enabled (TX_ENABLE_STACK_CHECKING is defined),
+ the TX_DISABLE_STACK_FILLING define is canceled, thereby forcing the stack
+ fill which is necessary for the stack checking logic.
+*/
+
+#ifdef TX_ENABLE_STACK_CHECKING
+#undef TX_DISABLE_STACK_FILLING
+#endif
+
+
+/*
+ Define the TX_THREAD control block extensions for this port. The main
+ reason for the multiple macros is so that backward compatibility can
+ be maintained with existing ThreadX kernel awareness modules.
+*/
+
+#if XCHAL_CP_NUM > 0
+#define TX_CP_THREAD_EXTENSION \
+ /* Co-proc state save areas, with padding for alignment: */ \
+ UINT tx_thread_cp_state[(XT_CP_SIZE+3)/4];
+#else
+#define TX_CP_THREAD_EXTENSION
+#endif
+
+#define TX_THREAD_EXTENSION_0 \
+ /* These extensions needs to be accessed from assembly code at context switches */ \
+ UINT tx_thread_solicited; /* Non-zero indicates solicited entry */ \
+ TX_CLIB_THREAD_EXTENSION /* Ptr to C library re-ent struct */ \
+ TX_CP_THREAD_EXTENSION /* Coprocessor state save areas */
+
+#define TX_THREAD_EXTENSION_1 \
+ TX_CLIB_THREAD_EXTENSION_END
+
+#define TX_THREAD_EXTENSION_2
+
+/* Execution profile related */
+#define TX_THREAD_EXTENSION_3 \
+ unsigned long long tx_thread_execution_time_total; \
+ unsigned long tx_thread_execution_time_last_start;
+
+
+/* Define the port extensions of the remaining ThreadX objects. */
+
+#define TX_BLOCK_POOL_EXTENSION
+#define TX_BYTE_POOL_EXTENSION
+#define TX_EVENT_FLAGS_GROUP_EXTENSION
+#define TX_MUTEX_EXTENSION
+#define TX_QUEUE_EXTENSION
+#define TX_SEMAPHORE_EXTENSION
+#define TX_TIMER_EXTENSION
+
+
+/* Define the user extension field of the thread control block. Nothing
+ additional is needed for this port so it is defined as white space. */
+
+#ifndef TX_THREAD_USER_EXTENSION
+#define TX_THREAD_USER_EXTENSION
+#endif
+
+
+/* Define the macros for processing extensions in tx_thread_create, tx_thread_delete,
+ tx_thread_shell_entry, and tx_thread_terminate. */
+
+#if XCHAL_CP_NUM > 0
+extern void _xt_coproc_release(void * coproc_sa_base);
+
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr) \
+ _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) \
+ _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) \
+ _xt_coproc_release(&thread_ptr->tx_thread_cp_state);
+#define TX_THREAD_CP_EXTENSION(thread_ptr) \
+ /* Initialize XT_CP_ASA ptr to aligned save area: */ \
+ /* NOTE: keep this matched with xtensa_context.h. */ \
+ thread_ptr->tx_thread_cp_state[0] = 0; \
+ thread_ptr->tx_thread_cp_state[1] = 0; \
+ thread_ptr->tx_thread_cp_state[2] = \
+ ((((UINT)thread_ptr->tx_thread_cp_state)+12+XCHAL_TOTAL_SA_ALIGN-1) \
+ & -XCHAL_TOTAL_SA_ALIGN);
+#else
+#define TX_THREAD_DELETE_EXTENSION(thread_ptr)
+#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr)
+#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr)
+#define TX_THREAD_CP_EXTENSION(thread_ptr)
+#endif
+
+#define TX_THREAD_CREATE_EXTENSION(thread_ptr) \
+ TX_THREAD_CLIB_EXTENSION(thread_ptr) \
+ TX_THREAD_CP_EXTENSION(thread_ptr)
+
+
+/* Define the ThreadX object creation extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_CREATE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_CREATE_EXTENSION(group_ptr)
+#define TX_MUTEX_CREATE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_CREATE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_CREATE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_CREATE_EXTENSION(timer_ptr)
+
+
+/* Define the ThreadX object deletion extensions for the remaining objects. */
+
+#define TX_BLOCK_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_BYTE_POOL_DELETE_EXTENSION(pool_ptr)
+#define TX_EVENT_FLAGS_GROUP_DELETE_EXTENSION(group_ptr)
+#define TX_MUTEX_DELETE_EXTENSION(mutex_ptr)
+#define TX_QUEUE_DELETE_EXTENSION(queue_ptr)
+#define TX_SEMAPHORE_DELETE_EXTENSION(semaphore_ptr)
+#define TX_TIMER_DELETE_EXTENSION(timer_ptr)
+
+
+/*
+ Define ThreadX interrupt lockout and restore macros for protection
+ on access of critical kernel information. The restore interrupt macro
+ must restore the interrupt posture of the running thread prior to the
+ value present prior to the disable macro. In most cases, the save area
+ macro is used to define a local function save area for the disable and
+ restore macros.
+*/
+
+extern unsigned int _tx_thread_interrupt_control(unsigned int new_posture);
+
+#define TX_INTERRUPT_SAVE_AREA register unsigned int interrupt_save;
+
+#ifdef TX_DISABLE_INLINE_MACROS
+#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE);
+#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save);
+#else
+#define TX_DISABLE interrupt_save = xthal_disable_interrupts();
+#define TX_RESTORE xthal_restore_interrupts(interrupt_save);
+#endif
+
+
+/* Define the interrupt lockout macros for each ThreadX object. */
+
+#define TX_BLOCK_POOL_DISABLE TX_DISABLE
+#define TX_BYTE_POOL_DISABLE TX_DISABLE
+#define TX_EVENT_FLAGS_GROUP_DISABLE TX_DISABLE
+#define TX_MUTEX_DISABLE TX_DISABLE
+#define TX_QUEUE_DISABLE TX_DISABLE
+#define TX_SEMAPHORE_DISABLE TX_DISABLE
+
+
+#if XCHAL_HAVE_XEA3
+/* Variables that keep track of the timer and software interrupt numbers in use. */
+extern int xt_sw_intnum;
+extern int xt_timer_intnum;
+#endif
+
+
+/* Define the version ID of ThreadX. This may be utilized by the application. */
+
+#ifdef TX_THREAD_INIT
+CHAR _tx_version_id[] =
+ "Copyright (c) Microsoft Corporation. * Azure RTOS Xtensa Version 6.1.3 *";
+#else
+extern CHAR _tx_version_id[];
+#endif
+
+#endif /* #ifndef __ASSEMBLER__ */
+
+#endif
+
diff --git a/ports/xtensa/xcc/inc/tx_user.h b/ports/xtensa/xcc/inc/tx_user.h
new file mode 100644
index 00000000..db17d428
--- /dev/null
+++ b/ports/xtensa/xcc/inc/tx_user.h
@@ -0,0 +1,257 @@
+/**************************************************************************/
+/* */
+/* 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 */
+/** */
+/** User Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_user.h PORTABLE C */
+/* 6.0.1 */
+/* */
+/* AUTHOR */
+/* */
+/* William E. Lamie, Microsoft Corporation */
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains user defines for configuring ThreadX in specific */
+/* ways. This file will have an effect only if the application and */
+/* ThreadX library are built with TX_INCLUDE_USER_DEFINE_FILE defined. */
+/* Note that all the defines in this file may also be made on the */
+/* command line when building ThreadX library and application objects. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 06-30-2020 William E. Lamie Initial Version 6.0.1 */
+/* */
+/**************************************************************************/
+
+#ifndef TX_USER_H
+#define TX_USER_H
+
+
+/* Define various build options for the ThreadX port. The application should either make changes
+ here by commenting or un-commenting the conditional compilation defined OR supply the defines
+ though the compiler's equivalent of the -D option.
+
+ For maximum speed, the following should be defined:
+
+ TX_MAX_PRIORITIES 32
+ TX_DISABLE_PREEMPTION_THRESHOLD
+ TX_DISABLE_REDUNDANT_CLEARING
+ TX_DISABLE_NOTIFY_CALLBACKS
+ TX_NOT_INTERRUPTABLE
+ TX_TIMER_PROCESS_IN_ISR
+ TX_REACTIVATE_INLINE
+ TX_DISABLE_STACK_FILLING
+ TX_INLINE_THREAD_RESUME_SUSPEND
+
+ For minimum size, the following should be defined:
+
+ TX_MAX_PRIORITIES 32
+ TX_DISABLE_PREEMPTION_THRESHOLD
+ TX_DISABLE_REDUNDANT_CLEARING
+ TX_DISABLE_NOTIFY_CALLBACKS
+ TX_NOT_INTERRUPTABLE
+ TX_TIMER_PROCESS_IN_ISR
+
+ Of course, many of these defines reduce functionality and/or change the behavior of the
+ system in ways that may not be worth the trade-off. For example, the TX_TIMER_PROCESS_IN_ISR
+ results in faster and smaller code, however, it increases the amount of processing in the ISR.
+ In addition, some services that are available in timers are not available from ISRs and will
+ therefore return an error if this option is used. This may or may not be desirable for a
+ given application. */
+
+
+/* Override various options with default values already assigned in tx_port.h. Please also refer
+ to tx_port.h for descriptions on each of these options. */
+
+/*
+#define TX_MAX_PRIORITIES 32
+#define TX_MINIMUM_STACK ????
+#define TX_THREAD_USER_EXTENSION ????
+#define TX_TIMER_THREAD_STACK_SIZE ????
+#define TX_TIMER_THREAD_PRIORITY ????
+*/
+
+/* Determine if timer expirations (application timers, timeouts, and tx_thread_sleep calls
+ should be processed within the a system timer thread or directly in the timer ISR.
+ By default, the timer thread is used. When the following is defined, the timer expiration
+ processing is done directly from the timer ISR, thereby eliminating the timer thread control
+ block, stack, and context switching to activate it. */
+
+/*
+#define TX_TIMER_PROCESS_IN_ISR
+*/
+
+/* Determine if in-line timer reactivation should be used within the timer expiration processing.
+ By default, this is disabled and a function call is used. When the following is defined,
+ reactivating is performed in-line resulting in faster timer processing but slightly larger
+ code size. */
+
+/*
+#define TX_REACTIVATE_INLINE
+*/
+
+/* Determine is stack filling is enabled. By default, ThreadX stack filling is enabled,
+ which places an 0xEF pattern in each byte of each thread's stack. This is used by
+ debuggers with ThreadX-awareness and by the ThreadX run-time stack checking feature. */
+
+/*
+#define TX_DISABLE_STACK_FILLING
+*/
+
+/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is
+ disabled. When the following is defined, ThreadX thread stack checking is enabled. If stack
+ checking is enabled (TX_ENABLE_STACK_CHECKING is defined), the TX_DISABLE_STACK_FILLING
+ define is negated, thereby forcing the stack fill which is necessary for the stack checking
+ logic. */
+
+/*
+#define TX_ENABLE_STACK_CHECKING
+*/
+
+/* Determine if preemption-threshold should be disabled. By default, preemption-threshold is
+ enabled. If the application does not use preemption-threshold, it may be disabled to reduce
+ code size and improve performance. */
+
+/*
+#define TX_DISABLE_PREEMPTION_THRESHOLD
+*/
+
+/* Determine if global ThreadX variables should be cleared. If the compiler startup code clears
+ the .bss section prior to ThreadX running, the define can be used to eliminate unnecessary
+ clearing of ThreadX global variables. */
+
+/*
+#define TX_DISABLE_REDUNDANT_CLEARING
+*/
+
+/* Determine if no timer processing is required. This option will help eliminate the timer
+ processing when not needed. The user will also have to comment out the call to
+ tx_timer_interrupt, which is typically made from assembly language in
+ tx_initialize_low_level. Note: if TX_NO_TIMER is used, the define TX_TIMER_PROCESS_IN_ISR
+ must also be used. */
+
+/*
+#define TX_NO_TIMER
+#ifndef TX_TIMER_PROCESS_IN_ISR
+#define TX_TIMER_PROCESS_IN_ISR
+#endif
+*/
+
+/* Determine if the notify callback option should be disabled. By default, notify callbacks are
+ enabled. If the application does not use notify callbacks, they may be disabled to reduce
+ code size and improve performance. */
+
+/*
+#define TX_DISABLE_NOTIFY_CALLBACKS
+*/
+
+
+/* Determine if the tx_thread_resume and tx_thread_suspend services should have their internal
+ code in-line. This results in a larger image, but improves the performance of the thread
+ resume and suspend services. */
+
+/*
+#define TX_INLINE_THREAD_RESUME_SUSPEND
+*/
+
+
+/* Determine if the internal ThreadX code is non-interruptable. This results in smaller code
+ size and less processing overhead, but increases the interrupt lockout time. */
+
+/*
+#define TX_NOT_INTERRUPTABLE
+*/
+
+
+/* Determine if the trace event logging code should be enabled. This causes slight increases in
+ code size and overhead, but provides the ability to generate system trace information which
+ is available for viewing in TraceX. */
+
+/*
+#define TX_ENABLE_EVENT_TRACE
+*/
+
+
+/* Determine if block pool performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various block pool performance information. */
+
+/*
+#define TX_BLOCK_POOL_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if byte pool performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various byte pool performance information. */
+
+/*
+#define TX_BYTE_POOL_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if event flags performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various event flags performance information. */
+
+/*
+#define TX_EVENT_FLAGS_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if mutex performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various mutex performance information. */
+
+/*
+#define TX_MUTEX_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if queue performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various queue performance information. */
+
+/*
+#define TX_QUEUE_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if semaphore performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various semaphore performance information. */
+
+/*
+#define TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if thread performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various thread performance information. */
+
+/*
+#define TX_THREAD_ENABLE_PERFORMANCE_INFO
+*/
+
+/* Determine if timer performance gathering is required by the application. When the following is
+ defined, ThreadX gathers various timer performance information. */
+
+/*
+#define TX_TIMER_ENABLE_PERFORMANCE_INFO
+*/
+
+#endif
+
diff --git a/ports/xtensa/xcc/inc/xtensa_api.h b/ports/xtensa/xcc/inc/xtensa_api.h
new file mode 100644
index 00000000..10255838
--- /dev/null
+++ b/ports/xtensa/xcc/inc/xtensa_api.h
@@ -0,0 +1,125 @@
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Xtensa-specific API for RTOS ports. */
+/**************************************************************************/
+
+#ifndef XTENSA_API_H
+#define XTENSA_API_H
+
+#include
+
+#include "xtensa_context.h"
+
+
+/* Typedef for C-callable interrupt handler function */
+typedef void (*xt_handler)(void *);
+
+/* Typedef for C-callable exception handler function */
+typedef void (*xt_exc_handler)(XtExcFrame *);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to set a handler for the specified exception.
+
+ n - Exception number (type)
+ f - Handler function address, NULL to uninstall handler.
+
+ The handler will be passed a pointer to the exception frame, which is created
+ on the stack of the thread that caused the exception.
+
+ If the handler returns, the thread context will be restored and the faulting
+ instruction will be retried. Any values in the exception frame that are
+ modified by the handler will be restored as part of the context. For details
+ of the exception frame structure see xtensa_context.h.
+-------------------------------------------------------------------------------
+*/
+extern xt_exc_handler xt_set_exception_handler(uint32_t n, xt_exc_handler f);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to set a handler for the specified interrupt.
+
+ n - Interrupt number.
+ f - Handler function address, NULL to uninstall handler.
+ arg - Argument to be passed to handler.
+-------------------------------------------------------------------------------
+*/
+extern xt_handler xt_set_interrupt_handler(uint32_t n, xt_handler f, void * arg);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to enable the specified interrupt.
+
+ intnum - Interrupt number to be enabled.
+
+ Returns: Nothing.
+-------------------------------------------------------------------------------
+*/
+extern void xt_interrupt_enable(uint32_t intnum);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to disable the specified interrupt.
+
+ intnum - Interrupt number to be disabled.
+
+ Returns: Nothing.
+-------------------------------------------------------------------------------
+*/
+extern void xt_interrupt_disable(uint32_t intnum);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to trigger the specified (s/w) interrupt.
+
+ intnum - Interrupt number to be triggered.
+
+ Returns: Nothing.
+-------------------------------------------------------------------------------
+*/
+extern void xt_interrupt_trigger(uint32_t intnum);
+
+
+/*
+-------------------------------------------------------------------------------
+ Call this function to clear the specified (s/w or edge-triggered)
+ interrupt.
+
+ intnum - Interrupt number to be cleared.
+
+Returns: Nothing.
+-------------------------------------------------------------------------------
+*/
+extern void xt_interrupt_clear(uint32_t intnum);
+
+
+#endif /* XTENSA_API_H */
+
diff --git a/ports/xtensa/xcc/inc/xtensa_context.h b/ports/xtensa/xcc/inc/xtensa_context.h
new file mode 100644
index 00000000..c2f76afa
--- /dev/null
+++ b/ports/xtensa/xcc/inc/xtensa_context.h
@@ -0,0 +1,561 @@
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************
+
+ XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
+
+ This header contains definitions and macros for use primarily by Xtensa
+ RTOS assembly source files. It includes and uses the Xtensa hardware
+ abstraction layer (HAL) to deal with config specifics. It may also be
+ included in C source files.
+
+ NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
+
+***************************************************************************/
+
+#ifndef XTENSA_CONTEXT_H
+#define XTENSA_CONTEXT_H
+
+#ifdef __ASSEMBLER__
+#include
+#endif
+
+#include
+#include
+#include
+
+#if defined (__ASSEMBLER__)
+#include "tx_api_asm.h"
+#endif
+
+
+/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
+#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
+
+
+/*
+-------------------------------------------------------------------------------
+ Macros that help define structures for both C and assembler.
+-------------------------------------------------------------------------------
+*/
+#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
+
+#define XSTRUCT_BEGIN .pushsection .text; .struct 0
+#define XSTRUCT_FIELD(ctype,size,asname,name) asname: .space size
+#define XSTRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n)
+#define XSTRUCT_END(sname) sname##Size:; .popsection
+
+#else
+
+#define XSTRUCT_BEGIN typedef struct {
+#define XSTRUCT_FIELD(ctype,size,asname,name) ctype name;
+#define XSTRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n];
+#define XSTRUCT_END(sname) } sname;
+
+#endif //_ASMLANGUAGE || __ASSEMBLER__
+
+
+/*
+-------------------------------------------------------------------------------
+ INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
+
+ A stack frame of this structure is allocated for any interrupt or exception.
+ It goes on the current stack. If the RTOS has a system stack for handling
+ interrupts, every thread stack must allow space for just one interrupt stack
+ frame, then nested interrupt stack frames go on the system stack.
+
+ The frame includes basic registers (explicit) and "extra" registers introduced
+ by user TIE or the use of the MAC16 option in the user's Xtensa config.
+ The frame size is minimized by omitting regs not applicable to user's config.
+
+ For Windowed ABI, this stack frame includes the interruptee's base save area,
+ another base save area to manage gcc nested functions, and a little temporary
+ space to help manage the spilling of the register windows.
+-------------------------------------------------------------------------------
+*/
+
+#if XCHAL_HAVE_XEA2
+
+XSTRUCT_BEGIN
+XSTRUCT_FIELD (long, 4, XT_STK_EXIT, exit) /* exit point for dispatch */
+XSTRUCT_FIELD (long, 4, XT_STK_PC, pc) /* return PC */
+XSTRUCT_FIELD (long, 4, XT_STK_PS, ps) /* return PS */
+XSTRUCT_FIELD (long, 4, XT_STK_A0, a0)
+XSTRUCT_FIELD (long, 4, XT_STK_A1, a1) /* stack pointer before interrupt */
+XSTRUCT_FIELD (long, 4, XT_STK_A2, a2)
+XSTRUCT_FIELD (long, 4, XT_STK_A3, a3)
+XSTRUCT_FIELD (long, 4, XT_STK_A4, a4)
+XSTRUCT_FIELD (long, 4, XT_STK_A5, a5)
+XSTRUCT_FIELD (long, 4, XT_STK_A6, a6)
+XSTRUCT_FIELD (long, 4, XT_STK_A7, a7)
+XSTRUCT_FIELD (long, 4, XT_STK_A8, a8)
+XSTRUCT_FIELD (long, 4, XT_STK_A9, a9)
+XSTRUCT_FIELD (long, 4, XT_STK_A10, a10)
+XSTRUCT_FIELD (long, 4, XT_STK_A11, a11)
+XSTRUCT_FIELD (long, 4, XT_STK_A12, a12)
+XSTRUCT_FIELD (long, 4, XT_STK_A13, a13)
+XSTRUCT_FIELD (long, 4, XT_STK_A14, a14)
+XSTRUCT_FIELD (long, 4, XT_STK_A15, a15)
+XSTRUCT_FIELD (long, 4, XT_STK_SAR, sar)
+XSTRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
+XSTRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
+#if XCHAL_HAVE_LOOPS
+XSTRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
+XSTRUCT_FIELD (long, 4, XT_STK_LEND, lend)
+XSTRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
+#endif
+#if XCHAL_HAVE_EXCLUSIVE
+XSTRUCT_FIELD (long, 4, XT_STK_ATOMCTL, atomctl)
+#endif
+#ifndef __XTENSA_CALL0_ABI__
+/* Temporary space for saving stuff during window spill */
+XSTRUCT_FIELD (long, 4, XT_STK_TMP0, tmp0)
+XSTRUCT_FIELD (long, 4, XT_STK_TMP1, tmp1)
+XSTRUCT_FIELD (long, 4, XT_STK_TMP2, tmp2)
+#endif
+#ifdef XT_USE_SWPRI
+/* Storage for virtual priority mask */
+XSTRUCT_FIELD (long, 4, XT_STK_VPRI, vpri)
+#endif
+#ifdef XT_USE_OVLY
+/* Storage for overlay state */
+XSTRUCT_FIELD (long, 4, XT_STK_OVLY, ovly)
+#endif
+XSTRUCT_END(XtExcFrame)
+
+#endif /* XCHAL_HAVE_XEA2 */
+
+#if XCHAL_HAVE_XEA3
+
+XSTRUCT_BEGIN
+XSTRUCT_FIELD (long, 4, XT_STK_ATOMCTL, atomctl)
+XSTRUCT_FIELD (long, 4, XT_STK_LCOUNT, lcount)
+XSTRUCT_FIELD (long, 4, XT_STK_LEND, lend)
+XSTRUCT_FIELD (long, 4, XT_STK_LBEG, lbeg)
+XSTRUCT_FIELD (long, 4, XT_STK_PC, pc)
+XSTRUCT_FIELD (long, 4, XT_STK_PS, ps)
+XSTRUCT_FIELD (long, 4, XT_STK_EXCCAUSE, exccause)
+XSTRUCT_FIELD (long, 4, XT_STK_EXCVADDR, excvaddr)
+#ifdef __XTENSA_CALL0_ABI__
+XSTRUCT_FIELD (long, 4, XT_STK_A0, a0)
+XSTRUCT_FIELD (long, 4, XT_STK_A1, a1)
+XSTRUCT_FIELD (long, 4, XT_STK_A2, a2)
+XSTRUCT_FIELD (long, 4, XT_STK_A3, a3)
+XSTRUCT_FIELD (long, 4, XT_STK_A4, a4)
+XSTRUCT_FIELD (long, 4, XT_STK_A5, a5)
+XSTRUCT_FIELD (long, 4, XT_STK_A6, a6)
+XSTRUCT_FIELD (long, 4, XT_STK_A7, a7)
+#endif
+XSTRUCT_FIELD (long, 4, XT_STK_A8, a8)
+XSTRUCT_FIELD (long, 4, XT_STK_A9, a9)
+XSTRUCT_FIELD (long, 4, XT_STK_A10, a10)
+XSTRUCT_FIELD (long, 4, XT_STK_A11, a11)
+XSTRUCT_FIELD (long, 4, XT_STK_A12, a12)
+XSTRUCT_FIELD (long, 4, XT_STK_A13, a13)
+XSTRUCT_FIELD (long, 4, XT_STK_A14, a14)
+XSTRUCT_FIELD (long, 4, XT_STK_A15, a15)
+#ifdef __XTENSA_WINDOWED_ABI__
+XSTRUCT_AFIELD(long, 4, XT_STK_SPILL, spill, 8)
+#endif
+XSTRUCT_END(XtExcFrame)
+
+#endif /* XCHAL_HAVE_XEA3 */
+
+#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
+#define XT_STK_NEXT1 XtExcFrameSize
+#else
+#define XT_STK_NEXT1 sizeof(XtExcFrame)
+#endif
+
+
+/* Allocate extra storage if needed for non-CP TIE state. Allow for alignment
+ padding as needed.
+ */
+#if XCHAL_EXTRA_SA_SIZE != 0
+
+#if XCHAL_EXTRA_SA_ALIGN <= 16
+#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
+#else
+/* If need more alignment than stack, add space for dynamic alignment */
+#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) + XCHAL_EXTRA_SA_ALIGN)
+#endif
+#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
+
+#else
+
+/* No extra storage required */
+#define XT_STK_NEXT2 XT_STK_NEXT1
+
+#endif
+
+
+#if XCHAL_HAVE_XEA3
+
+/* Total frame size */
+#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2))
+
+/* Exception/interrupt frame size */
+#define XT_STK_XFRM_SZ XT_STK_NEXT1
+
+/* Extra save area size (including alignment padding) */
+#define XT_STK_XTRA_SZ (XT_STK_FRMSZ - XT_STK_XFRM_SZ)
+
+/* Alignment padding area size */
+#if XCHAL_EXTRA_SA_SIZE != 0
+#define XT_STK_ALIGN_SZ (XT_STK_EXTRA - XT_STK_NEXT1)
+#endif
+
+#else
+
+/*
+-------------------------------------------------------------------------------
+ This is the frame size. Add space for 4 registers (interruptee's base save
+ area) and some space for gcc nested functions if any.
+-------------------------------------------------------------------------------
+*/
+#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+ CO-PROCESSOR STATE SAVE AREA FOR A THREAD
+
+ The RTOS must provide an area per thread to save the state of co-processors
+ when that thread does not have control. Co-processors are context-switched
+ lazily (on demand) only when a new thread uses a co-processor instruction,
+ otherwise a thread retains ownership of the co-processor even when it loses
+ control of the processor. An Xtensa co-processor exception is triggered when
+ any co-processor instruction is executed by a thread that is not the owner,
+ and the context switch of that co-processor is then peformed by the handler.
+ Ownership represents which thread's state is currently in the co-processor.
+
+ Co-processors may not be used by interrupt or exception handlers. If an
+ co-processor instruction is executed by an interrupt or exception handler,
+ the co-processor exception handler will trigger a kernel panic and freeze.
+ This restriction is introduced to reduce the overhead of saving and restoring
+ co-processor state (which can be quite large) and in particular remove that
+ overhead from interrupt handlers.
+
+ The co-processor state save area may be in any convenient per-thread location
+ such as in the thread control block or above the thread stack area. It need
+ not be in the interrupt stack frame since interrupts don't use co-processors.
+
+ Along with the save area for each co-processor, two bitmasks with flags per
+ co-processor (laid out as in the CPENABLE reg) help manage context-switching
+ co-processors as efficiently as possible:
+
+ XT_CPENABLE
+ The contents of a non-running thread's CPENABLE register.
+ It represents the co-processors owned (and whose state is still needed)
+ by the thread. When a thread is preempted, its CPENABLE is saved here.
+ When a thread solicits a context-swtich, its CPENABLE is cleared - the
+ compiler has saved the (caller-saved) co-proc state if it needs to.
+ When a non-running thread loses ownership of a CP, its bit is cleared.
+ When a thread runs, it's XT_CPENABLE is loaded into the CPENABLE reg.
+ Avoids co-processor exceptions when no change of ownership is needed.
+
+ XT_CPSTORED
+ A bitmask with the same layout as CPENABLE, a bit per co-processor.
+ Indicates whether the state of each co-processor is saved in the state
+ save area. When a thread enters the kernel, only the state of co-procs
+ still enabled in CPENABLE is saved. When the co-processor exception
+ handler assigns ownership of a co-processor to a thread, it restores
+ the saved state only if this bit is set, and clears this bit.
+
+ XT_CP_CS_ST
+ A bitmask with the same layout as CPENABLE, a bit per co-processor.
+ Indicates whether callee-saved state is saved in the state save area.
+ Callee-saved state is saved by itself on a solicited context switch,
+ and restored when needed by the coprocessor exception handler.
+ Unsolicited switches will cause the entire coprocessor to be saved
+ when necessary.
+
+ XT_CP_ASA
+ Pointer to the aligned save area. Allows it to be aligned more than
+ the overall save area (which might only be stack-aligned or TCB-aligned).
+ Especially relevant for Xtensa cores configured with a very large data
+ path that requires alignment greater than 16 bytes (ABI stack alignment).
+-------------------------------------------------------------------------------
+*/
+
+#if XCHAL_CP_NUM > 0
+
+/* Offsets of each coprocessor save area within the 'aligned save area': */
+#define XT_CP0_SA 0
+#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
+#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
+#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
+#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
+#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
+#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
+#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
+#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
+
+/* Offsets within the overall save area: */
+#define XT_CPENABLE 0 /* (2 bytes) coprocessors active for this thread */
+#define XT_CPSTORED 2 /* (2 bytes) coprocessors saved for this thread */
+#define XT_CP_CS_ST 4 /* (2 bytes) coprocessor callee-saved regs stored for this thread */
+#define XT_CP_ASA 8 /* (4 bytes) ptr to aligned save area */
+/* Overall size allows for dynamic alignment: */
+#define XT_CP_SIZE (12 + XT_CP_SA_SIZE + XCHAL_TOTAL_SA_ALIGN)
+#else
+#define XT_CP_SIZE 0
+#endif
+
+
+/*
+-------------------------------------------------------------------------------
+ MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
+
+ Convenient where the frame size requirements are the same for both ABIs.
+ ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
+ ENTRY0, RET0 are for frameless functions (no locals, no calls).
+
+ where size = size of stack frame in bytes (must be >0 and aligned to 16).
+ For framed functions the frame is created and the return address saved at
+ base of frame (Call0 ABI) or as determined by hardware (Windowed ABI).
+ For frameless functions, there is no frame and return address remains in a0.
+ Note: Because CPP macros expand to a single line, macros requiring multi-line
+ expansions are implemented as assembler macros.
+-------------------------------------------------------------------------------
+*/
+
+#ifdef __ASSEMBLER__
+#ifdef __XTENSA_CALL0_ABI__
+ /* Call0 */
+ #define ENTRY(sz) entry1 sz
+ .macro entry1 size=0x10
+ addi sp, sp, -\size
+ s32i a0, sp, 0
+ .endm
+ #define ENTRY0
+ #define RET(sz) ret1 sz
+ .macro ret1 size=0x10
+ l32i a0, sp, 0
+ addi sp, sp, \size
+ ret
+ .endm
+ #define RET0 ret
+#else
+ /* Windowed */
+#if XCHAL_HAVE_XEA3
+ #define ENTRY(sz) entry sp, (sz + 0x20)
+ #define ENTRY0 entry sp, 0x20
+#else
+ #define ENTRY(sz) entry sp, (sz + 0x10)
+ #define ENTRY0 entry sp, 0x10
+#endif
+ #define RET(sz) retw
+ #define RET0 retw
+#endif
+#endif
+
+
+/*
+-------------------------------------------------------------------------------
+ This flag is meant for internal use. Have all interrupts be dispatched via a
+ common wrapper, which takes care of doing some OS-specific stuff common to
+ all interrupt handlers. Said stuff cannot safely be handled in the RTOS_ENTER
+ and RTOS_EXIT macros.
+-------------------------------------------------------------------------------
+*/
+#if (defined TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || (defined XT_INTEXC_HOOKS)
+#define XT_USE_INT_WRAPPER 1
+#else
+#define XT_USE_INT_WRAPPER 0
+#endif
+
+#if XCHAL_HAVE_XEA3
+#ifdef XT_USE_SWPRI
+//#warning "Software prioritization of interrupts (XT_USE_SWPRI) not supported for XEA3."
+#endif
+
+#ifdef __ASSEMBLER__
+
+ // RTOS-specific entry macro. Use only a8, a12-a14.
+
+ .macro XT_RTOS_INT_ENTER
+
+ .endm
+
+ // RTOS-specific exit macro. Use only a8-a14.
+ // (In call0, a15 holds user SP, must be preserved)
+
+ .macro XT_RTOS_INT_EXIT
+
+ // Check nesting count and branch on nest state.
+ movi a8, _tx_thread_system_state
+ movi a9, _tx_thread_execute_ptr // a9 <- &_tx_thread_execute_ptr (new)
+ movi a10, _tx_thread_preempt_disable // a10 <- &_tx_thread_preempt_disable
+ l32i a8, a8, 0
+ bnez a8, .Lnested // state != 0 means nested
+
+ movi a8, _tx_thread_current_ptr // a8 <- &_tx_thread_current_ptr (old)
+ l32i a9, a9, 0 // a9 <- _tx_thread_execute_ptr
+ l32i a11, a8, 0 // a11 <- _tx_thread_current_ptr
+ beqz a11, .Lsched // no old thread, go to scheduler
+ l32i a10, a10, 0 // a10 <- _tx_thread_preempt_disable
+ beq a11, a9, .Lnested // no change, restore current thread
+ bgei a10, 1, .Lnested // no preemption, restore current thread
+
+ // Preemption, save remaining state of current (outgoing) thread
+
+ movi a12, _tx_timer_time_slice // a12 <- &_tx_timer_time_slice
+ addi a10, a1, -XT_STK_FRMSZ
+ s32i a10, a11, tx_thread_stack_ptr // save outgoing thread stack pointer
+ l32i a10, a12, 0 // a10 <- _tx_timer_time_slice
+ s32i a10, a11, tx_thread_time_slice // save outgoing time slice value
+ movi a10, 0
+ s32i a10, a12, 0 // disable time slice
+ s32i a10, a11, tx_thread_solicited // mark as preempted
+ s32i a10, a8, 0 // Clear _tx_thread_current_ptr
+#if XCHAL_CP_NUM > 0
+ rsr a12, CPENABLE // Save and clear CPENABLE
+ s16i a12, a11, tx_thread_cp_state + XT_CPENABLE
+ wsr a10, CPENABLE
+#endif
+
+ // Save non-CP TIE state if any
+#if XCHAL_EXTRA_SA_SIZE > 0
+ addi a10, a1, -XT_STK_FRMSZ + XT_STK_ALIGN_SZ // where to save
+#if XCHAL_EXTRA_SA_ALIGN > 16
+ movi a12, -XCHAL_EXTRA_SA_ALIGN
+ and a10, a10, a12 // align dynamically >16 bytes
+#endif
+ xchal_ncp_store a10, a11, a12, a13, a14
+#endif
+
+ // If windowed ABI, a0-a7 was not saved by dispatch code.
+ // These don't go into the exception frame, but below the
+ // exception frame pointer.
+
+#ifdef __XTENSA_WINDOWED_ABI__
+ addi a10, a1, -XT_STK_FRMSZ -32
+ s32i a0, a10, 0
+ s32i a2, a10, 8
+ s32i a3, a10, 12
+ s32i a4, a10, 16
+ s32i a5, a10, 20
+ s32i a6, a10, 24
+ s32i a7, a10, 28
+#endif
+
+.Lsched:
+ // When we get here, interrupts are disabled, a8 = &_tx_thread_current_ptr,
+ // a9 = _tx_thread_execute_ptr
+ movi a9, _tx_thread_execute_ptr // a9 <- &_tx_thread_execute_ptr (new)
+ l32i a9, a9, 0 // a9 <- _tx_thread_execute_ptr
+ s32i a9, a8, 0 // _tx_thread_current_ptr = _tx_thread_execute_ptr
+ beqz a9, _xt_idle // go idle if _tx_thread_execute_ptr == 0
+ l32i a10, a9, tx_thread_run_count
+ l32i a11, a9, tx_thread_time_slice
+ movi a12, _tx_timer_time_slice
+ addi a10, a10, 1
+ s32i a10, a9, tx_thread_run_count
+ s32i a11, a12, 0 // _tx_timer_time_slice = _tx_thread_current_ptr->tx_thread_time_slice
+
+#ifdef TX_THREAD_SAFE_CLIB
+ #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+ movi a10, _impure_ptr
+ #elif XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ movi a10, _reent_ptr
+ #else
+ #error TX_THREAD_SAFE_CLIB defined with unsupported C library.
+ #endif
+ l32i a11, a9, tx_thread_clib_ptr
+ s32i a11, a10, 0
+#endif
+
+#if XCHAL_CP_NUM > 0
+ l16ui a10, a9, tx_thread_cp_state + XT_CPENABLE
+ wsr a10, CPENABLE // restore CPENABLE
+#endif
+
+ l32i a1, a9, tx_thread_stack_ptr // SP = _tx_thread_execute_ptr->tx_thread_stack_ptr
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ // Call the thread entry function to indicate the thread is executing.
+ // SP should be pointing to a safe region at this point.
+#ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_execution_thread_enter
+#else
+ call8 _tx_execution_thread_enter
+#endif
+#endif
+
+ l32i a2, a9, tx_thread_solicited // a2 = solicited flag
+ beqz a2, 1f
+
+ // Solicited restore
+ addi a1, a1, XT_STK_FRMSZ // restore original SP
+ addi a2, a1, -XT_STK_XFRM_SZ
+ l32i a3, a2, XT_STK_PC // a3 = return PC
+
+ movi a2, PS_DI
+ xps a2, a2 // disable interrupts
+ movi a2, 0
+ wsr.ms a2 // restore normal DISPST
+ rsync
+ jx a3 // return to yield point
+
+1:
+ // Preempt restore
+#if XCHAL_EXTRA_SA_SIZE > 0
+ addi a10, a1, XT_STK_ALIGN_SZ // where to restore from
+#if XCHAL_EXTRA_SA_ALIGN > 16
+ movi a12, -XCHAL_EXTRA_SA_ALIGN
+ and a10, a10, a12 // align dynamically >16 bytes
+#endif
+ xchal_ncp_load a10, a11, a12, a13, a14
+#endif
+
+#ifdef __XTENSA_WINDOWED_ABI__
+ // Restore a0-a7 for windowed ABI
+ addi a8, a1, -32
+ l32i a0, a8, 0
+ l32i a2, a8, 8
+ l32i a3, a8, 12
+ l32i a4, a8, 16
+ l32i a5, a8, 20
+ l32i a6, a8, 24
+ l32i a7, a8, 28
+#else
+ // For call0, dispatch exit code expects a15 = original SP
+ addi a15, a1, XT_STK_FRMSZ
+#endif
+
+ addi a1, a1, XT_STK_FRMSZ // set up SP for dispatch exit
+
+.Lnested:
+ // Return to the current saved context.
+
+ .endm
+
+#endif /* __ASSEMBLER__ */
+#endif /* XCHAL_HAVE_XEA3 */
+
+#endif /* XTENSA_CONTEXT_H */
+
diff --git a/ports/xtensa/xcc/inc/xtensa_rtos.h b/ports/xtensa/xcc/inc/xtensa_rtos.h
new file mode 100644
index 00000000..03db1849
--- /dev/null
+++ b/ports/xtensa/xcc/inc/xtensa_rtos.h
@@ -0,0 +1,204 @@
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************
+
+ RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
+
+ This header is the primary glue between generic Xtensa RTOS support
+ sources and a specific RTOS port for Xtensa. It contains definitions
+ and macros for use primarily by Xtensa assembly coded source files.
+
+ Macros in this header map callouts from generic Xtensa files to specific
+ RTOS functions. It may also be included in C source files.
+
+ Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
+ architecture, using the Xtensa hardware abstraction layer (HAL) to deal
+ with configuration specifics.
+
+ Should be included by all Xtensa generic and RTOS port-specific sources.
+
+***************************************************************************/
+
+#ifndef XTENSA_RTOS_H
+#define XTENSA_RTOS_H
+
+#ifdef __ASSEMBLER__
+#include
+#else
+#include
+#include
+#endif
+
+#include
+#include
+#include
+
+/*
+Include any RTOS specific definitions that are needed by this header.
+*/
+#include "tx_user.h"
+
+/*
+Name of RTOS (for messages).
+*/
+#define XT_RTOS_NAME ThreadX
+
+/*
+Check some Xtensa configuration requirements and report error if not met.
+Error messages can be customize to the RTOS port.
+*/
+
+#if !XCHAL_HAVE_XEA2 && !XCHAL_HAVE_XEA3
+#error "ThreadX/Xtensa requires Xtensa Exception Architecture v2 (XEA2) or higher."
+#endif
+
+
+/***************************************************************************
+
+RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS.
+
+Define callout macros used in generic Xtensa code to interact with the RTOS.
+The macros are simply the function names for use in calls from assembler code.
+Some of these functions may call back to generic functions in xtensa_context.h .
+
+***************************************************************************/
+
+/*
+Inform RTOS of entry into an interrupt handler that will affect it.
+Allows RTOS to manage switch to any system stack and count nesting level.
+Called after minimal context has been saved, with interrupts disabled.
+RTOS port can call0 _xt_context_save to save the rest of the context.
+May only be called from assembly code by the 'call0' instruction.
+*/
+// void XT_RTOS_INT_ENTER(void)
+#define XT_RTOS_INT_ENTER _tx_thread_context_save
+
+/*
+Inform RTOS of completion of an interrupt handler, and give control to
+RTOS to perform thread/task scheduling, switch back from any system stack
+and restore the context, and return to the exit dispatcher saved in the
+stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore
+to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save,
+leaving only a minimal part of the context to be restored by the exit
+dispatcher. This function does not return to the place it was called from.
+May only be called from assembly code by the 'call0' instruction.
+*/
+// void XT_RTOS_INT_EXIT(void)
+#define XT_RTOS_INT_EXIT _tx_thread_context_restore
+
+/*
+Convenience macros to disable and enable interrupts.
+*/
+#if XCHAL_HAVE_XEA3
+#define XT_INTS_DISABLE(reg) movi reg, PS_DI; xps reg, reg
+#define XT_INTS_ENABLE(reg) wsr reg, PS; rsync
+#else
+#define XT_INTS_DISABLE(reg) rsil reg, XCHAL_EXCM_LEVEL
+#define XT_INTS_ENABLE(reg) wsr reg, PS; rsync
+#endif
+
+/*
+Inform RTOS of the occurrence of a tick timer interrupt.
+If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
+May be coded in or called from C or assembly, per ABI conventions.
+*/
+#ifndef TX_NO_TIMER
+// void XT_RTOS_TIMER_INT(void)
+#define XT_RTOS_TIMER_INT _tx_timer_interrupt
+#endif
+
+/*
+Return in a15 the base address of the co-processor state save area for the
+thread that triggered a co-processor exception, or 0 if no thread was running.
+The state save area is structured as defined in xtensa_context.h and has size
+XT_CP_SIZE. Co-processor instructions should only be used in thread code, never
+in interrupt handlers or the RTOS kernel. May only be called from assembly code
+and by the 'call0' instruction. A result of 0 indicates an unrecoverable error.
+The implementation may use only a2-4, a15 (all other regs must be preserved).
+*/
+// void* XT_RTOS_CP_STATE(void)
+#define XT_RTOS_CP_STATE _tx_thread_coproc_state
+
+
+/***************************************************************************
+
+HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL.
+
+This Xtensa RTOS port provides hooks for dynamically installing exception
+and interrupt handlers to facilitate automated testing where each test
+case can install its own handler for user exceptions and each interrupt
+priority (level). This consists of an array of function pointers indexed
+by interrupt priority, with index 0 being the user exception handler hook.
+Each entry in the array is initially 0, and may be replaced by a function
+pointer of type XT_INTEXC_HOOK. A handler may be uninstalled by installing 0.
+
+The handler for low and medium priority obeys ABI conventions so may be coded
+in C. For the exception handler, the cause is the contents of the EXCCAUSE
+reg, and the result is -1 if handled, else the cause (still needs handling).
+For interrupt handlers, the cause is a mask of pending enabled interrupts at
+that level, and the result is the same mask with the bits for the handled
+interrupts cleared (those not cleared still need handling). This allows a test
+case to either pre-handle or override the default handling for the exception
+or interrupt level (see xtensa_vectors.S).
+
+High priority handlers (including NMI) must be coded in assembly, are always
+called by 'call0' regardless of ABI, must preserve all registers except a0,
+and must not use or modify the interrupted stack. The hook argument 'cause'
+is not passed and the result is ignored, so as not to burden the caller with
+saving and restoring a2 (it assumes only one interrupt per level - see the
+discussion in high priority interrupts in xtensa_vectors.S). The handler
+therefore should be coded to prototype 'void h(void)' even though it plugs
+into an array of handlers of prototype 'uint32_t h(uint32_t)'.
+
+To enable interrupt/exception hooks, compile the RTOS with '-DXT_INTEXC_HOOKS'.
+
+***************************************************************************/
+
+#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)
+
+#ifndef __ASSEMBLER__
+typedef uint32_t (*XT_INTEXC_HOOK)(uint32_t cause);
+extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
+#endif
+
+
+/***************************************************************************
+
+CONVENIENCE INCLUSIONS.
+
+Ensures RTOS specific files need only include this one Xtensa-generic header.
+These headers are included last so they can use the RTOS definitions above.
+
+***************************************************************************/
+
+#include "xtensa_context.h"
+
+#ifdef XT_RTOS_TIMER_INT
+#include "xtensa_timer.h"
+#endif
+
+
+#endif /* XTENSA_RTOS_H */
+
diff --git a/ports/xtensa/xcc/inc/xtensa_timer.h b/ports/xtensa/xcc/inc/xtensa_timer.h
new file mode 100644
index 00000000..d5a29ed5
--- /dev/null
+++ b/ports/xtensa/xcc/inc/xtensa_timer.h
@@ -0,0 +1,157 @@
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************
+ XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
+
+ This header contains timer related definitions and macros for use by
+ Xtensa RTOS source files. It includes and uses the Xtensa hardware
+ abstraction layer (HAL) to deal with config specifics.
+
+ If the RTOS has no timer interrupt, then there is no tick timer and the
+ clock frequency is irrelevant, so all of these macros are left undefined
+ and the Xtensa core configuration need not have a timer.
+***************************************************************************/
+
+#ifndef XTENSA_TIMER_H
+#define XTENSA_TIMER_H
+
+#include "xtensa_rtos.h" /* in case this wasn't included directly */
+
+#ifdef XT_RTOS_TIMER_INT /* skip all this stuff if no timer int */
+
+#ifdef __ASSEMBLER__
+#include
+#else
+#include
+#endif
+
+#include
+#include
+
+
+#if XCHAL_HAVE_XEA3
+
+/*
+If the user has not specified a timer by defining XT_TIMER_INDEX, then
+select timer 0.
+*/
+#ifndef XT_TIMER_INDEX
+#define XT_TIMER_INDEX 0
+#endif
+
+#else /* XEA2 */
+
+/*
+Select timer to use for periodic tick, and determine its interrupt number
+and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
+in which case its validity is checked (it must exist in this core and must
+not be on a high priority interrupt - an error will be reported in invalid).
+Otherwise select the first low or medium priority interrupt timer available.
+*/
+#ifndef XT_TIMER_INDEX
+ #if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
+ #if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
+ #undef XT_TIMER_INDEX
+ #define XT_TIMER_INDEX 3
+ #endif
+ #endif
+ #if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
+ #if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
+ #undef XT_TIMER_INDEX
+ #define XT_TIMER_INDEX 2
+ #endif
+ #endif
+ #if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
+ #if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
+ #undef XT_TIMER_INDEX
+ #define XT_TIMER_INDEX 1
+ #endif
+ #endif
+ #if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
+ #if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
+ #undef XT_TIMER_INDEX
+ #define XT_TIMER_INDEX 0
+ #endif
+ #endif
+#endif
+
+#endif /* XCHAL_HAVE_XEA3 */
+
+#ifndef XT_TIMER_INDEX
+ #error "There is no suitable timer in this Xtensa configuration."
+#endif
+
+#define XT_CCOMPARE (CCOMPARE + XT_TIMER_INDEX)
+#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
+#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
+
+#if XCHAL_HAVE_XEA2
+#define XT_TIMER_INTEN (1 << XT_TIMER_INTNUM)
+#endif
+
+#if XT_TIMER_INDEX == 0
+#define XT_WSR_CCOMPARE XT_WSR_CCOMPARE0
+#elif XT_TIMER_INDEX == 1
+#define XT_WSR_CCOMPARE XT_WSR_CCOMPARE1
+#elif XT_TIMER_INDEX == 2
+#define XT_WSR_CCOMPARE XT_WSR_CCOMPARE2
+#endif
+
+#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
+ #error "The timer selected by XT_TIMER_INDEX does not exist in this core."
+#elif !XCHAL_HAVE_XEA3 && (XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL)
+ #error "The timer interrupt cannot be high priority (use medium or low)."
+#endif
+
+/*
+Default number of timer ticks per second. This can be redefined as required
+either by editing here or by overriding from the command line during build.
+*/
+#ifndef XT_TICK_PER_SEC
+#define XT_TICK_PER_SEC 100
+#endif
+
+/*
+Set processor clock frequency and determine clock divisor for timer tick.
+If using a supported board via the board-independent API defined in xtbsp.h,
+this may be left undefined but XT_BOARD must be defined. The frequency and
+tick divisor will be computed during run-time initialization.
+*/
+#ifndef XT_BOARD
+#ifndef XT_CLOCK_FREQ
+#define XT_CLOCK_FREQ 1000000
+#endif
+#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
+#else
+#ifndef __ASSEMBLER__
+extern uint32_t xt_tick_divisor;
+extern void xt_tick_divisor_init(void);
+#endif
+#define XT_TICK_DIVISOR xt_tick_divisor
+#endif /* XT_BOARD */
+
+#endif /* XT_RTOS_TIMER_INT */
+#endif /* XTENSA_TIMER_H */
+
diff --git a/ports/xtensa/xcc/readme_threadx.txt b/ports/xtensa/xcc/readme_threadx.txt
new file mode 100644
index 00000000..90fc92d7
--- /dev/null
+++ b/ports/xtensa/xcc/readme_threadx.txt
@@ -0,0 +1,1015 @@
+ Microsoft's ThreadX for Xtensa Configurable Processors
+
+ Using the Xtensa Tools
+
+1. Xtensa Configuration Requirements and Restrictions
+
+The Xtensa configurable architecture supports a vast space of processor
+features. This port of ThreadX to the Xtensa architecture is based on
+a Cadence Design Systems RTOS porting layer that takes care of Xtensa specifics
+that are common to most embedded real-time operating systems. It supports all
+Xtensa features (including context-switching custom processor extensions
+defined in the TIE language) with certain minimum requirements. You
+must use Xtensa Tools to compile and link ThreadX for your particular
+configuration. ThreadX uses the Xtensa Hardware Abstraction Layer (HAL)
+to adapt your ThreadX compilation to your particular Xtensa processor
+configuration. ThreadX also provides optional thread-safe support for
+the Xtensa C library and the newlib C library distributed with Xtensa Tools
+(for use in threads only, not in interrupt handlers).
+
+ThreadX for Xtensa configurable processors requires the following minimum
+processor configuration options:
+- Timer interrupt option with at least one interruptible timer for ThreadX.
+- Interrupt option (implied by the timer interrupt option).
+- Xtensa Exception Architecture 2 (XEA2) or Exception Architecture 3 (XEA3).
+ Please note that XEA1 is NOT supported.
+
+Minimal support for certain evaluation boards is provided via a board
+independent "XTBSP" API implemented by a board specific library. This
+provides the board clock frequency and basic polled drivers for the display
+and console I/O device (usually a UART), and ThreadX can be built to
+take advantage of these (note: it is not specific to ThreadX and is not a
+traditional RTOS "board support package" with RTOS specific interrupt-driven
+drivers). Note that ThreadX can run on any Xtensa board without
+this board support (a "raw" platform), but you will have to provide the
+clock frequency and drivers for any on-board devices you want to use.
+
+
+2. Building the ThreadX run-time Library
+
+By default, you will build for the Xtensa instruction set simulator. If
+you have a supported emulation board, you can build to run on that. You
+can also build to run on a raw Xtensa core with no "board support", a
+good starting point for supporting your own target platform. Cadence Design Systems
+recommends doing functional development on the simulator because it
+is easier to debug with, then move to a board if/when you need to test
+hardware drivers or real-time performance.
+
+ThreadX/Xtensa comes with a Makefile as well as DOS .bat file, taking
+advantage of xt-make, a version of GNU make that comes with Xtensa Tools
+(you can just as well use generic GNU make if you have it installed).
+The Makefile works on any host platform and provides for incremental builds.
+The .bat file works on DOS/Windows only and always cleans before building.
+The build for each target platform is placed in a sub-directory so several
+platform builds can coexist even with incremental rebuilds.
+
+First, make sure you have installed Xtensa Tools and your processor
+configuration, and be sure that Xtensa Tools are in your search path.
+
+If you wish to build for an evaluation board that is supported by an
+external package, be sure the appropriate package is installed. See the
+introduction (section 0) to determine if you need an external package.
+If you are using an external board package, set the environment variable
+XTENSA_BOARDS to the absolute path of the root of the installed support
+package (or you can pass this to xt-make commands on the command line).
+eg. XTENSA_BOARDS = C:\usr\xtensa\RB-2007.1-xtav60 for Avnet LX60 board.
+You do not need to set XTENSA_BOARDS if using a Cadence Design Systems supported
+board with Xtensa Tools RB-2007.2 and up (support is bundled with the tools).
+
+Next, change directories to the ThreadX installation directory, as follows:
+
+> cd c:\threadx\xtensa\gnu
+
+Now build the ThreadX library (tx.a) by executing the build_threadx.bat
+batch file (or using the Makefile directly) while inside the threadx
+directory, as follows:
+
+> build_threadx.bat
+
+which always builds for the simulator (but you can edit it), or
+
+> xt-make
+
+which by default builds for the simulator (PLATFORM=sim), or either of
+
+> xt-make PLATFORM=board BOARD=
+or
+> xt-make BOARD=
+
+which builds for a specified supported board (note PLATFORM=board is
+default when BOARD is defined). eg. BOARD=xtav60 for the Avnet LX60
+(XT-AV60) board.
+
+> xt-make PLATFORM=raw
+
+which builds for a raw Xtensa core with no "board support".
+
+> xt-make PLATFORM=gdbio
+
+Provides some very slow I/O support through the xt-gdb debugger.
+For GDBIO to work, xt-gdb must remain connected to the target.
+
+If you are building for an Xtensa processor configuration that is not the
+default you selected when you installed Xtensa Tools, you need to define the
+environment variable XTENSA_CORE. If your configuration is not in the
+default registry you selected when you installed Xtensa Tools, you also
+need to define the environment variable XTENSA_SYSTEM. See tools manuals.
+You can avoid defining these in your environment if you pass the variables
+you need to redefine into xt-make as follows:
+
+> xt-make XTENSA_CORE= XTENSA_SYSTEM= ...
+
+There are more details about build options in the comment in the Makefile.
+
+At this point, all the ThreadX objects are located in a library file: tx.a .
+This file must be linked with your application in order to use ThreadX.
+This library and all the intermediate object files are placed in a platform
+specific sub-directory named the same as BOARD or PLATFORM (if BOARD is not
+defined), for example "sim", "xtkc705".
+
+To build ThreadX with thread-safe C library support, define TX_THREAD_SAFE_CLIB
+in your build, as described in section 5 and in the Makefile. Please note
+that the C library is only safe for use in threads, not in interrupt handlers.
+It may also safely be used in tx_application_define (after tx_kernel_enter,
+before threads are running).
+
+
+3. Demonstration System
+
+The ThreadX demonstration is designed to execute under Xtensa instruction set
+simulator (ISS) or on a supported evaluation board programmed with your Xtensa
+processor configuration.
+
+Building the demonstration is easy, simply execute the build_threadx_demo.bat
+batch file while inside threadx directory, as follows:
+
+> build_threadx_demo.bat
+
+or
+
+> xt-make demo
+
+Be sure to set or pass into xt-make the variables described in section 2 above
+for building the ThreadX library, including the PLATFORM or BOARD you want to
+run on.
+
+This compiles demo_threadx.c (which is the demonstration application) and links
+it with the ThreadX objects in tx.a. The resulting file demo_threadx.out is a
+ELF binary file that can be downloaded and executed on the target.
+
+The demo binary appears in the platform specific sub-directory described earlier.
+For the following commands, change to that directory or prepend it as the path
+of demo_threadx.out.
+
+
+To execute on the simulator:
+
+> xt-run [--turbo] demo_threadx.out
+
+The option --turbo provides much faster, but non-cycle-accurate simulation.
+Refer to the Xtensa simulator user manual for further simulator options.
+
+
+To execute on the simulator using the Xplorer GUI based debugger:
+
+> xplorer --debug demo_threadx.out
+
+
+To execute on a supported evaluation board, download demo_threadx.out per
+instructions in the tools manuals. Be sure the board has been programmed
+with the correct configuration and is set up to boot from RAM and debug
+a downloaded program! Optionally you may connect a terminal or terminal
+emulator to the serial port on the board with settings as described in
+the board user manual, and see the output of printf on the terminal (if
+the demo was compiled with DEMO_USE_PRINTF or DEMO_USE_XTUTIL).
+
+To obtain I/O on a "raw" platform such as an unsupported board, you need
+to provide low level I/O drivers (eg. inbyte() and outbyte() for character
+I/O if you want to use printf etc.). You can run "raw" executables on
+any Xtensa platform, including simulator and any board, but you will not
+see any behavior specific to the platform (eg. display, printed output,
+stopping simulation at end of program). You can, while debugging, use a
+debugger mechanism called GDBIO to obtain basic I/O. Use PLATFORM=GDBIO
+on your xt-make command line - this is the same as "raw" except it links
+some stubs that communicate through the debugger. It is very slow!
+
+WARNING: It is tempting to add printf calls to other threads in the demo.
+If you modify the code in any way, you may need adjust affected threads'
+stack sizes. This is especially true if you add a printf call. See 4.5.
+
+
+4. System Initialization
+
+4.1 ThreadX Kernel
+
+ThreadX uses the reset vector and low level initialization from the Xtensa
+libraries provided by the linker support package (LSP). It does not provide
+its own reset vector (which would have to be maintained with tools upgrades).
+
+ThreadX is initialized by tx_kernel_enter which is usually called from
+main. The primary initialization function is _tx_initialize_low_level
+and is located in the file tx_initialize_low_level.c. This function is
+responsible for setting up various system data structures. Interrupt and
+exception vectors are linked into your program and installed at load time
+(they are not dynamically installed). The interrupt and exception vectors
+for the ThreadX Xtensa port are defined in xtensa_vectors.S (for XEA2) and
+xtensa_vectors_xea3.S (for XEA3).
+
+4.2 Memory Allocation
+
+In addition, _tx_initialize_low_level also determines the first available
+address for use by the application. By default, the first available address
+is assumed to be above all linker-allocated sections at symbol _end. This
+is passed to the application definition function, tx_application_define.
+This is a convenience to the application developer. Ultimately the developer
+has full control over memory allocation and can choose to use this or not.
+The top of available memory is not provided and should be obtained from the
+tools if needed.
+
+4.3 Location and Extent of System (Interrupt) Stack
+
+ThreadX/Xtensa supports a user-definable system stack. By default, the
+top of the system stack is defined by the symbol _xt_interrupt_stack_top.
+See the file xtensa_intr_asm.S for the default system stack definition.
+This stack may be resized and/or relocated according to the application
+needs. The application developer must ensure that the system stack is
+sized appropriately for the application. All interrupts handled by
+ThreadX will use the system stack. Handlers written in assembly must
+not switch to the system stack, since it will not be possible to detect
+whether the stack is currently in use.
+
+The macro TX_SYSTEM_STACK_SIZE defines the size of the system stack.
+As a convenience, a macro TX_MINIMUM_STACK_SYSTEM is provided with the
+minimum size required for the system stack. This is based on the maximum
+possible interrupt nesting level per the Xtensa processor configuration,
+assuming very simple C handlers that do not call deeper than one or two
+levels. If the application uses more complex handlers, it will be
+necessary to add to this value (accounting for nesting) to determine
+the space required for the system stack.
+
+4.4 Location and Extent of C Library Heap
+
+If the optional thread-safe support for the C library is used, memory
+for the heap is allocated like this: by default, half the space between
+the first available memory address and the end of system memory is
+made available to the heap.
+
+The heap location and limit are available in two global variables, and
+can be fully customized in tx_application_define by assigning to them:
+
+ _tx_clib_heap_start Base address of heap.
+ _tx_clib_heap_end Upper limit address to which heap can grow.
+
+This must be done BEFORE any C library calls. It is advised that it be
+done at the beginning of tx_application_define.
+
+Please note that when the thread-safe C library support is used, the heap
+is not initialized before tx_kernel_enter has been called, so malloc will
+fail. It is recommended to avoid C library calls that use the heap (such
+as printf) outside of ThreadX (eg. in main). The C library is NOT safe
+for use in interrupt or exception handlers, so this should be avoided.
+
+4.5 Thread Stack Sizes
+
+The application must ensure that every thread has enough space for its
+stack. This must account for the deepest call depth and allow for one
+interrupt stack frame as defined in xtensa_context.h . Several factors
+influence the size of the stack required, including compiler optimization
+level (-O0 is worst), use of TX_ENABLE_STACK_CHECKING option, and of
+course your Xtensa configuration. Some stack size guidelines and macros
+are provided in tx_port.h assuming no optimization (default, -O0).
+
+Threads that call C library functions may need larger stacks than those
+that don't. In particular, use of printf requires a very large stack and
+will usually cause a stack overflow if inserted in a thread without
+enlarging its stack size. See DEMO_STACK_SIZE_PRINTF in demo_threadx.c
+for a guideline. Use printf with care!
+
+
+5. Assembler / Compiler Switches
+
+The following are compiler switches used in building the ThreadX library
+and demonstration system. These can be supplied by editing the Makefile
+or by overriding the COPT or CFLAGS variables in the make command line
+(eg. make COPT="-O2 -DTX_THREAD_SAFE_CLIB"). More details in Makefile.
+
+Compiler Switch Meaning
+
+ -g Specifies debug information.
+ -c Specifies object code generation.
+ -On Sets compiler optimization level n (default -O0).
+ -mlongcalls Allows assembler and linker to convert call
+ instructions to longer indirect call sequences
+ when target is out of range.
+ -x assembler-with-cpp Passes .s and .S files through C preprocessor.
+ -Dmacro Define a preprocessor macro with no value.
+ -Dmacro=value Define a preprocessor macro with a value.
+
+Application Defines (preprocessor macros definable with the -D option):
+
+ TX_THREAD_SAFE_CLIB Enable support for thread-safe C library.
+ Only the Xtensa C library and the newlib library
+ are supported for thread-safe operation.
+ When this is enabled, half the available memory
+ space is allocated by default, below the system
+ stack, for the heap. The heap size and location
+ can be customized in tx_application_define.
+ Default off.
+
+ NOTE: Thread safe support for Xtensa C library requires Xtensa Tools
+ version RF-2015.2 or later.
+
+ TX_ENABLE_STACK_CHECKING Enable generic ThreadX support for stack
+ overflow checking. This can help avoid long
+ debugging sessions or customer support calls
+ by identifying many crashes caused by stack
+ overflow. Use of this option adds a small
+ premium to the required thread stack sizes
+ (the premium is included by the stack size
+ convenience macros defined in tx_port.h).
+
+ TX_NO_TIMER Enable generic ThreadX footprint reduction when
+ no periodic tick is needed. The Xtensa port also
+ reduces footprint by removing all code related
+ to timer interrupts. Related XT_* options below
+ (XT_CLOCK_FREQ, XT_TICK_PER_SEC, XT_TIMER_INDEX)
+ have no effect under TX_NO_TIMER.
+
+ All generic ThreadX options in tx_user.h may also be defined with -D.
+
+ Note, the above defines are not specific to Xtensa processors, so
+ their names begin with "TX_". Defines below are unique to the Xtensa
+ port so have names beginning with "XT_".
+
+ XT_SIMULATOR Set this if building to run on the simulator.
+ Takes advantage of certain simulator control
+ and reporting facilities, and adjusts timing
+ of periodic tick to provide a more acceptable
+ performance in simulation (see XT_CLOCK_FREQ).
+ Set by default unless PLATFORM is overridden.
+
+ XT_BOARD=board Set this if building for a supported board.
+ The value should be the identifier of a board
+ supported in the Xtensa Tools or an external
+ package (eg. XT_BOARD=xtkc705 for the Xilinx
+ KC705 board). If the board is supported by an
+ external package, the variable XTENSA_BOARDS
+ should point to the root of the package. Set by
+ provided Makefile when PLATFORM=board and BOARD
+ is defined (eg. PLATFORM=board BOARD=xtkc705).
+
+ XT_CLOCK_FREQ=freq Specifies the target processor's clock
+ frequency in Hz. Used primarily to set the
+ timer that generates the periodic interrupt.
+ Defaults are provided and may be edited in
+ xtensa_timer.h (see comments there also).
+ Default for simulator provides more acceptable
+ performance, but cannot provide real-time
+ performance due to variation in simulation
+ speed per host platform and insufficient
+ cycles between interrupts to process them.
+ Supported board platforms by default leave
+ this undefined and compute the clock frequency
+ at initialization unless this is explicitly
+ defined.
+
+ XT_TICK_PER_SEC=n Specifies the frequency of the periodic tick.
+
+ XT_TIMER_INDEX=n Specifies which timer to use for ThreadX.
+ Set this if your Xtensa processor configuration
+ provides more than one suitable timer and you
+ want to override the default. See xtensa_timer.h.
+
+ XT_INTEXC_HOOKS Enables hooks in interrupt vector handlers
+ to support dynamic installation of exception
+ and interrupt handlers. Used by automatic
+ regression test programs. Disabled by default.
+
+ XT_USE_OVLY Enable code overlay support.
+
+ XT_USE_SWPRI Enable software prioritization of interrupts.
+ Enabling this will prioritize interrupts with
+ higher bit numbers over those with lower bit
+ numbers at the same level. This works only for
+ low and medium priority interrupts that can be
+ dispatched to C handlers.
+
+ TX_SYSTEM_STACK_SIZE=n Specify the size of the interrupt stack, which
+ is the stack that all interrupt handlers switch
+ to while handling interrupts. See the section
+ describing the interrupt stack for more details.
+
+
+6. Register Usage and Stack Frames
+
+The Xtensa architecture specifies two ABIs that determine how the general
+purpose registers a0-a15 are used: the windowed ABI, and the Call0 ABI.
+The choice of ABI is made when configuring the processor or its associated
+software. Xtensa processors may have other special registers (including
+coprocessor registers and other TIE "states") that are independent of this
+choice of ABI. See Xtensa documentation for more details.
+
+In the windowed ABI the registers of the current window are used as follows:
+ a0 = return address
+ a1 = stack pointer (alias sp)
+ a2 = first argument and result of call (in simple cases)
+ a3-7 = second through sixth arguments of call (in simple cases).
+ Note that complex or large arguments are passed on the
+ stack. Details are in the Xtensa Tools manuals.
+ a8-a15 = available for use as temporaries.
+
+There are no callee-save registers. The windowed hardware automatically
+saves registers a0-a3 on a call4, a0-a8 on a call8, a0-a12 on a call12,
+by rotating the register window. Hardware triggers window overflow and
+underflow exceptions as necessary when registers outside the current
+window need to be spilled to preallocated space in the stack frame, or
+restored. Complete details are in the Xtensa manuals. The entire windowed
+register file is saved and restored on interrupt or thread context switch.
+Note that only call0 and call8 are available in XEA3 Windowed ABI.
+
+The Call0 ABI does not make use of register windows, relying instead
+on a fixed set of 16 registers without window rotation.
+The Call0 ABI is more conventional and uses registers as follows:
+ a0 = return address
+ a1 = stack pointer (alias sp)
+ a2 = first argument and result of call (in simple cases)
+ a3-7 = second through sixth arguments of call (in simple cases).
+ Note that complex or large arguments are passed on the
+ stack. Details are in the Xtensa Tools manuals.
+ a8-a11 = scratch.
+ a12-a15 = callee-save (a function must preserve these for its caller).
+
+On a ThreadX API call, callee-save registers are saved only when a thread
+context switch occurs, and other registers are not saved at all (the caller
+does not expect them to be preserved). On an interrupt, callee-saved
+registers might only be saved and restored when a thread context-switch
+occurs, but all other registers are always saved and restored.
+
+An Xtensa processor has other special registers independent of the ABI,
+depending on the configuration (including coprocessor registers and other
+TIE state) that are part of the thread context. ThreadX preserves all such
+registers over an unsolicited context-switch triggered by an interrupt
+(including time-slice expiry). However it does NOT preserve these over
+a solicited context-switch during a ThreadX API call. This bears some
+explanation. These special registers are either ignored by the compiler
+or treated as caller-saved, meaning that if kept "live" over a function
+call (ie. need to be preserved) they must be saved and restored by the
+caller. Since solicited entry to ThreadX is always made by a function
+call, ThreadX assumes the caller has saved any of these registers that are
+"live". ThreadX avoids a lot of overhead by not having to save and restore
+every special register (there can be many) on every solicited context switch.
+
+As a consequence, the application developer should NOT assume that special
+registers are preserved over a ThreadX API call such as tx_thread_sleep.
+If multiple threads use a register, the caller must save and restore it.
+
+The saved context stack frames for context switches that occur as a result
+of interrupt handling (interrupt frame) or from thread-level API calls
+(solicited frame) are described in human readable form in xtensa_context.h .
+All suspended threads have one of these two types of stack frames. The top
+of the suspended thread's stack is pointed to by tx_thread_stack_ptr in the
+associated thread control block TX_THREAD. An Xtensa architecture port-specific
+extension to the thread control block tx_thread_solicited contains 1 for a
+thread that is currently suspended from an API call, otherwise contains 0.
+
+
+7. Improving Performance, Footprint, or Ease of Debugging
+
+The distribution version of ThreadX is built with debug (-g) and without
+compiler optimizations (-O0). This makes debugging easier inside ThreadX
+itself. Of course, -O0 costs some performance. To make ThreadX run faster,
+you can change the Makefile to enable the desired optimizations or set
+a predefined optimization level (-O) .
+
+Maximum performance is achieved with -O3, but that might increase footprint
+substantially. A good compromise is -O2. If code size is a concern, -Os may
+yield better results. See the compiler manual for details.
+
+You can eliminate the ThreadX basic API error checking by compiling your
+application code with the symbol TX_DISABLE_ERROR_CHECKING defined before
+tx_api.h is included.
+
+The Xtensa architecture port-specific assembly files are coded with no
+file-scope labels inside functions (all labels inside functions begin with
+".L"). This allows a profiler to accurately associate an address with a
+function, and also allows the debugger's stack trace to show the correct
+function wherever the program counter is within that function. However
+there are some tradeoffs in debugging. Local (".L") labels are not
+visible to the debugger, so the following limitations may be observed
+during debugging:
+- You cannot set a breakpoint on a local label inside a function.
+- Disassembly will show the entire function, but will get out of sync and
+ show incorrect opcodes if it crosses any padding before an aligned local
+ branch target (".L" label, not ".Ln"). Restart disassembly specifying an
+ address range explicitly between points where there is padding.
+Since ThreadX is provided in source form, it is not difficult to remove
+the ".L" and ".Ln" prefixes from local labels if you want them visible.
+They can also be made visible by passing the '-L' option to the assembler
+and linker (see the assembler and linker manuals for details).
+
+
+8. Interrupt and Exception Handling
+
+NOTE: The material in this section is mostly an overview. For a more
+detailed explanation please refer to the Xtensa ISA manual and the System
+Software manual.
+
+ThreadX provides a complete set of efficient exception and first-level
+interrupt handlers installed at the appropriate exception and interrupt
+vector locations. The XEA2 architecture supports several different
+classes of exceptions and interrupts. Being a configurable architecture,
+many of these are optional, and the vector locations are determined by
+your processor configuration. The handlers provided use conditional
+compilation to adapt to your processor configuration and include only
+the code that is needed.
+
+Xtensa vector locations may reside almost anywhere, including in ROM.
+And the amount of code space available at each of these locations is
+often very small (e.g. due to following vectors). A small stub of code
+installed at the vector jumps to the corresponding handler, usually in RAM.
+The exception and interrupt handlers are defined in xtensa_vectors.S .
+They are not specific to ThreadX, but call into ThreadX where appropriate
+via macros defined in xtensa_rtos.h .
+
+Interrupt/Exception Handling in XEA2
+------------------------------------
+
+The handlers provided for low and medium priority interrupts are just
+dispatchers that save relevant state and call user-definable handlers.
+See the files xtensa_vectors.S and xtensa_api.h for more details of how
+to create and install application-specific user interrupt handlers.
+Similarly, user-defined handlers can be installed for exceptions (other
+than a few which are always handled by the OS).
+
+The high priority interrupt handlers provided may be considered templates
+into which the application adds code to service specific interrupts.
+The places where application handlers should be inserted are tagged with
+the comment "USER_EDIT" in xtensa_vectors.S.
+
+This ThreadX port supports strict priority-based nesting of interrupts.
+An interrupt may only nest on top of one of strictly lower priority.
+Equal priority interrupts concurrently pending are handled in an
+application-defined sequence before any lower priority interrupts
+are handled. During interrupt and exception handling, the processor's
+interrupt level (PS.INTLEVEL) is used to control the interrupt priority
+level that can be accepted; interrupt sources are not controlled
+individually by ThreadX (the application is free to access the INTENABLE
+register directly to enable/disable individual interrupts, e.g. using
+Xtensa HAL services). This approach provides the most deterministic
+bounds on interrupt latency (for a given priority) and system stack depth.
+
+Software prioritization of interrupts at the same priority is controlled
+by the definition of XT_USE_SWPRI. See above for a description of this
+parameter.
+
+Interrupt and Exception Handling in XEA3
+----------------------------------------
+
+In XEA3 no distinction is made between low, medium and high priority interrupt
+levels. Interrupts at all levels up to the highest (NMI) level can be dispatched
+to handlers written in C. Interrupts are dispatched by the XEA3 dispatcher and
+the handlers are found from a handler table. Handlers are installed into the
+handler table by calling xt_set_interrupt_handler. As there is no concept of
+a high priority interrupt any longer, handlers can only be specified per
+interrupt, not per level. Since all levels can be handled in C, the value of
+EXCM_LEVEL is set to the highest possible level (NMI level).
+Software prioritization is not available for XEA3.
+
+
+The following subsections describe the handling of each class of exception
+and interrupt in more detail. Many have nothing to do with ThreadX but are
+mentioned because there is code to handle them in xtensa_vectors.S.
+
+8.1 User Exception and Interrupt Handler (Low/Medium Priority)
+
+ All Xtensa 'general exceptions' come to the user, kernel, or double
+ exception vector. The exception type is identified by the EXCCAUSE
+ special register (level 1 interrupts are one particular cause of a
+ general exception). This port sets up PS to direct all such exceptions
+ to the user vector. Exceptions taken at the other two vectors usually
+ indicate a kernel or application bug.
+
+ In XEA3, everything except a double exception will come to a common
+ vector. This vector saves the requisite processor state and then checks
+ for the highest priority interrupt to dispatch. If no interrupts are
+ pending then a check is made for exceptions.
+
+ Level 1 interrupts are identified at the beginning of the handler
+ and are dispatched to a dedicated handler. Then, syscall and alloca
+ exceptions are identified and dispatched to special handlers described
+ below. After this, coprocessor exceptions are identified and dispatched
+ to the coprocessor handler.
+
+ Any remaining exceptions are processed as follows:
+
+ Having allocated the exception stack frame, the user exception handler
+ calls _tx_thread_context_save, which saves the rest of the interrupt
+ context. After this the handler sets up a C environment and enables
+ the high-priority class of interrupts (which do not interact with
+ ThreadX), then reads EXCCAUSE and uses the cause (number) to index
+ into a table of user-specified handlers. The correct handler is then
+ called. If the handler returns, the context is restored and control
+ is returned to the code that caused the exception. The user-defined
+ handler may alter the saved context, or any other system state, that
+ allows the faulting instruction to be retried.
+
+ If the cause is a level 1 (low-priority) or medium-priority interrupt,
+ the handler enables all interrupts above that priority level after
+ saving the thread context and switching to the interrupt stack if it
+ is not a nested interrupt. It then sets up the environment for C code
+ and then calls the handler (found in the handler table) for the
+ interrupt number. If the user has not specified a handler, then the
+ default handler will be called, which will terminate the program.
+
+ If the interrupt is for the system timer, it calls a special interrupt
+ handler for the system timer tick, which calls _tx_timer_interrupt then
+ clears its bit from the mask. This interrupt cannot be hooked by the
+ user-defined handler.
+
+ Finally, the handler calls _tx_thread_context_restore to allow ThreadX
+ to perform any scheduling necessary and return either to the interrupted
+ thread or another.
+
+ If software prioritization is enabled, the handler will re-enable all
+ interrupts at the same level that are numerically higher than the current
+ one, before calling the user handler. This allows a higher priority
+ interrupt to pre-empt the lower priority handler.
+
+8.2 Medium Priority Interrupt Handlers (XEA2)
+
+ Medium priority interrupts are those at levels 2 up to XCHAL_EXCM_LEVEL,
+ a configuration-specific maximum interrupt level affected by the global
+ 'exception mode' bit in the processor status word (PS.EXCM).
+ Interrupt levels above XCHAL_EXCM_LEVEL are of the high-priority class.
+ The Xtensa hardware documentation considers medium priority interrupts
+ to be a special case of high-priority interrupts, but from a software
+ perspective they are very different.
+
+ Dispatch of medium-priority interrupts is discussed in the section
+ above.
+
+8.3 High Priority Interrupt Handlers (XEA2)
+
+ High priority interrupts are those strictly above XCHAL_EXCM_LEVEL,
+ a configuration-specific maximum interrupt level affected by the
+ global 'exception mode' bit in the processor status word (PS.EXCM).
+ High priority handlers may not directly interact with ThreadX at all,
+ and are described here only for the sake of completeness. They must
+ be coded in assembler (may not be coded in C) and are intended to be
+ used for handling extremely high frequency hardware events that need
+ to be handled in only a few cycles. A high priority interrupt handler
+ may trigger a software interrupt at a medium or low priority level to
+ occasionally signal ThreadX. Please see Xtensa documentation.
+
+ There is a separate vector and a few special registers for each high
+ priority interrupt, providing for fast dispatch and efficient nesting
+ on top of lower priority interrupts. Handlers are templates included
+ only for the vectors that exist in your Xtensa processor configuration.
+ These templates are written for only one interrupt per high priority
+ level to minimize latency servicing very fast time-critical interrupts.
+ The vector code jumps to the corresponding first-level interrupt handler,
+ which then executes application-provided assembler code before returning
+ quickly to the interrupted thread or lower priority handler.
+
+8.4 Kernel Exception Handler (XEA2)
+
+ Kernel mode is not used in this port of ThreadX, and therefore kernel
+ exceptions should not happen. A stub is provided for the vector that
+ triggers the debugger (if connected) or calls _xt_panic to freeze the
+ processor should a kernel exception occur.
+
+8.5 Alloca Exception Handler
+
+ Alloca exceptions are generated by the 'movsp' instruction, which
+ is used only in the windowed ABI. Its purpose is to allocate some
+ space on top of the stack. Because the window hardware may have
+ spilled some registers to the 16 byte "base save" area below the
+ stack pointer, it is necessary to protect those values. The alloca
+ handler accomplishes this quickly without setting up an interrupt
+ frame or entering ThreadX, by emulating a register underflow and
+ re-executing 'movsp'.
+
+8.6 Syscall Exception Handler
+
+ Syscall exceptions are generated by a 'syscall' instruction.
+ The windowed ABI specifies that executing this instruction with
+ a value of zero in register a2 must spill any unsaved registers
+ in the windowed register file to their pre-determined locations
+ on the caller's stack. The handler does exactly that, and skips
+ over the 'syscall' instruction before returning to the caller.
+ If a2 is non-zero, the handler returns a2 == -1 to the caller.
+
+8.7 Co-Processor Exception Handler
+
+ A coprocessor exception is generated when a thread accesses a
+ coprocessor that it does not "own". Ownership represents which
+ thread's state is currently in the coprocessor. Co-processors are
+ context-switched "lazily" (on demand) only when a non-owning thread
+ uses a coprocessor instruction, otherwise a thread retains ownership
+ even when it is preempted from the main processor. The coprocessor
+ exception handler performs the context-switch and manages ownership.
+
+ Co-processors may not be used by any code outside the context of a
+ thread. A coprocessor exception triggered by code that is not part
+ of a running thread is a fatal error and ThreadX/Xtensa will panic.
+ This restriction is intended to reduce the overhead of saving and
+ restoring coprocessor state (which can be quite large) and in
+ particular remove that overhead from interrupt handlers. It also
+ reduces the thread stack size requirement by allowing coprocessor
+ state to be saved in the thread control block rather than the stack.
+
+8.8 Debug Exception Handler
+
+ A debug exception is caused as a result of running code, such as by
+ a 'break' instruction or hardware breakpoints and watchpoints, or
+ as a result of an external debug interrupt, such as from an OCD based
+ debugger or multiprocessor debug events ("breakin/breakout"). If the
+ processor is running in OCD mode under control of an OCD-based debugger,
+ the trigger event immediately halts the processor and gives control to
+ the OCD debugger. Otherwise control is transferred to the debug vector.
+ The debug vector handler calls the simulator if running on the ISS,
+ which then takes control and interacts with any attached debugger.
+ If running on hardware and not in OCD mode, debug exceptions are not
+ expected, so the debug handler calls _xt_panic to freeze the processor.
+
+8.9 Double Exception Handler
+
+ A double exception is a general exception that happens while the
+ processor is in exception mode (PS.EXCM set), and thus indicates a
+ bug in kernel code. The double exception vector handler triggers
+ the debugger (if connected) or calls _xt_panic to freeze the
+ processor.
+
+8.10 Window Overflow and Underflow Exception Handlers
+
+ Window overflow and underflow handlers are required for use of the
+ windowed ABI. Each has its own dedicated vector and highly optimized
+ code that is independent of OS. See Xtensa documentation for details.
+
+8.11 Hooks for Dynamic Installation of Handlers
+
+ Optional hooks are provided in the user exception and low level
+ interrupt handler and all medium and high priority interrupt handlers,
+ to dynamically install a handler function (which may be coded in C,
+ unless in a high-priority interrupt handler). These hooks are enabled
+ and used by automatic regression tests, they are not part of a normal
+ ThreadX build. However an application is free to take advantage of
+ them. The interrupt/exception hooks are described in xtensa_rtos.h .
+
+ It is recommended that the application not make use of these hooks, but
+ rather use xt_set_interrupt_handler() and xt_set_exception_handler()
+ to install application-specific handlers. This method is more convenient
+ and allows arguments to be passed to the handlers. Software prioritization
+ of interrupts works only with this method. See xtensa_api.h for details.
+
+9. Overlay Support (XEA2 only)
+
+ThreadX supports the overlay feature of the Xtensa toolsuite. To enable overlay support,
+the ThreadX library should be built with XT_USE_OVLY defined. In addition, the linker
+command line must use the overlay library via the -loverlay linker option and the
+xtensa_overlay_os_hook.o object file must be explicitly specified in order to override
+the overlay libary version.
+
+You will also need to generate a custom LSP for overlay use. Please reference the
+Xtensa System Software Reference and Xtenas Linker Support Packages (LSPs) for more
+information on using overlays.
+
+
+10. Revision History
+
+For generic code revision information, please refer to the readme_threadx_generic.txt
+file, which is included in your distribution. The following details the revision
+information associated with this specific port of ThreadX:
+
+04/26/2019 ThreadX Xtensa version 5.12. This release adds support for the Xtensa XEA3
+ exception architecture and the Xtensa NX processor family. The following
+ changes/enhancements are included:
+
+ Makefile Changes to support building for Xtensa
+ XEA3 configurations.
+ xtensa_vectors_xea3.S New file added, interrupt and exception
+ dispatch code for XEA3.
+
+ tx_api_asm.h Changes and additions to support the Xtensa
+ tx_port.h XEA3 exception architecture.
+ xtensa_api.h
+ xtensa_context.h
+ xtensa_rtos.h
+ xtensa_timer.h
+ tx_initialize_low_level.c
+ tx_thread_context_restore.S
+ tx_thread_context_save.S
+ tx_thread_interrupt_control.c
+ tx_thread_schedule.S
+ tx_thread_stack_build.S
+ tx_thread_system_return.S
+ tx_timer_interrupt.S
+ tx_xtensa_stack_error_handler.c
+ xtensa_context.S
+ xtensa_coproc_handler.S
+ xtensa_init.c
+ xtensa_intr.c
+ xtensa_intr_asm.S
+ xtensa_intr_wrapper.c
+ xtensa_vectors.S
+
+08/01/2017 ThreadX Xtensa version 5.11. This release includes the following changes
+ and enhancements/modifications:
+
+ Makefile Build execution profile module only
+ if the module has been selected.
+ tx_api_asm.h Changed field offsets for Xtensa-
+ specific fields in TCB.
+ tx_clib_lock.c Added thread wrapper function to handle
+ C library setup and cleanup properly.
+ tx_port.h Redefined macros as required as part of
+ the redesigned C library thread safety support.
+ tx_xtensa_stack_error_handler.c Included required headers.
+ xtensa_intr_asm.S Placed interrupt stack explicitly in .data
+ section.
+ xtensa_intr.c Fixed return values for set exception handler
+ and set interrupt handler functions.
+ xtensa_overlay_os_hook.c Added conditions so that code is now compiled
+ only if overlay option is selected.
+ xtensa_timer.h Include TIE header files conditionally.
+ *.h Modified comment(s).
+ *.S Modified comment(s).
+
+03/22/2016 ThreadX Xtensa version 5.10. This release includes the following changes
+ and enhancements: separate user-configurable interrupt stack, support for
+ Xtensa C library (xclib) thread safety, minor changes to the support for
+ the Execution Profile kit, and minor changes to remove some compiler warnings.
+ This release includes the following modifications:
+
+ tx_port.h Added support for XCLIB C library thread safety,
+ added support for separate interrupt stack,
+ added support Execution Profile Kit (EPK), and
+ updated version string.
+ tx_initialize_low_level.S Replaced by tx_initialize_low_level.c, added
+ support for XCLIB C library thread safety,
+ added support for separate interrupt stack and
+ moved setup of thread stack check callback in here
+ from demo program.
+ tx_thread_context_restore.S Added support for Execution Profile Kit (EPK).
+ tx_thread_schedule.S Added support for Execution Profile Kit (EPK), and
+ added support for XCLIB C library thread safety.
+ tx_thread_system_return.S Added support for Execution Profile Kit (EPK).
+ tx_api_asm.h Added support for XCLIB C library thread safety.
+ tx_clib_lock.c Added support for XCLIB C library thread safety.
+ xtensa_api.h Corrected issues with function declarations.
+ xtensa_context.h Corrected build errors when TX_NO_TIMER defined.
+ xtensa_intr_asm.S Added support for separate interrupt stack.
+ xtensa_overlay_os_hook.c Corrected compiler warnings.
+ xtensa_vectors.S Added support for Execution Profile Kit (EPK), and
+ added compiler warnings.
+ xtensa_timer.h Added timer related defines to simplify timer setup code.
+ Makefile Various misc updates, removed some obsolete targets.
+ tx_intr_demo.c Added support for XCLIB C library thread safety.
+ *.h Modified comment(s).
+ *.S Modified comment(s).
+
+06/01/2015 ThreadX Xtensa version 5.9. This release includes the following modifications:
+
+ tx_port.h Changed default timer thread stack size logic,
+ updated coprocessor support, and updated
+ version string.
+ tx_initialize_low_level.S Modified timer setup.
+ tx_thread_schedule.S Added setup for timing test option.
+ tx_thread_stack_build.S Added virtual priority mask setup.
+ tx_thread_system_return.S Added support for coprocessor save.
+ xtensa_context.h Added additional interrupt support, including
+ coprocessor save/restore.
+ xtensa_context.S Added additional interrupt support, including
+ coprocessor save/restore.
+ xtensa_overlay_os_hook.c Added include of overlay.h.
+ xtensa_vectors.S Added new interrupt support and functionality.
+ xtensa_api.h Added new file for this release.
+ xtensa_intr.c Added new file for this release.
+ xtensa_intr_asm.S Added new file for this release.
+ *.h Modified comment(s).
+ *.S Modified comment(s).
+
+07/31/2014 ThreadX Xtensa version 5.8. This release includes the following modifications:
+
+ tx_port.h Added in-line interrupt disable and
+ restore macros, and updated version string.
+ tx_thread_system_return.S Added context save optimization.
+ xtensa_context.h Added overlay support.
+ xtensa_context.S Added overlay support.
+ xtensa_overlay_os_hook.c Added new file for overlay support.
+ *.h Modified comment(s).
+ *.S Modified comment(s).
+
+10/01/2011 ThreadX Xtensa version 5.7. This release includes the following modifications:
+
+ tx_port.h Updated version string.
+ tx_thread_context_restore.S Changed to 16-bit save of tx_thread_cp_state.
+ tx_thread_schedule.S Changed to 16-bit restore of tx_thread_cp_state.
+ tx_thread_system_return.S Changed to 16-bit save of tx_thread_cp_state.
+ xtensa_context.h Modified alignment constants and macros.
+ xtensa_context.S Removed initial alignment adjustment.
+ *.h Modified comment(s).
+ *.S Modified comment(s).
+
+07/15/2011 ThreadX Xtensa version 5.6. This release includes the following modifications:
+
+ tx_port.h Modified control block and thread processing
+ extensions to be compatible with all cores,
+ and updated version string.
+
+ tx_clib_lock.c Added code to not use priority inheritance when
+ running the regression testsuite.
+ tx_timer_interrupt.S Added code to optionally call user timer ISR.
+ xtensa_timer.h Adjusted timer for testsuite to pass under
+ simulation.
+ xtensa_vectors.S Fixed several issues in coprocessor context
+ switch code.
+ *.S Modified comment(s).
+
+01/28/2011 ThreadX Xtensa version 5.5. This release includes the following modifications:
+
+ tx_port.h Changed version ID and added alignment padding.
+ tx_thread_stack_build.s Added code to clear solicited stack frame flag.
+ xtensa_context.h Added logic to support Xtensa processors with
+ load/store units wider than 128-bits
+ xtensa_context.s Added logic to support Xtensa processors with
+ load/store units wider than 128-bits
+ xtensa_vectors.s Added logic to support Xtensa processors with
+ load/store units wider than 128-bits
+ *.s Modified comment(s).
+
+05/01/2010 ThreadX Xtensa version 5.4. This release includes the following modifications:
+
+ tx_port.h Changed version ID.
+ tx_thread_system_return.s Changed code to preserve current time-slice value.
+ *.s Modified comment(s).
+
+07/15/2009 ThreadX Xtensa version 5.3. It includes the following modifications:
+
+ tx_port.h Added include of string.h, added GDBIO
+ constants, and modified version ID string.
+ tx_clib_lock.c Added include of stdlib.h.
+ tx_thread_context_save.S Added "XCHAL_CP_NUM > 0" conditional around
+ _tx_thread_coproc_state function definition.
+ tx_thread_schedule.S Removed #else conditional and replaced RET
+ macro with assembly code.
+ tx_thread_system_return.S Replaced ENTRY macro with assembly code.
+ xtensa_context.h Modified call frame offsets.
+ xtensa_timer.h Modified timer constants and added extern
+ for _xt_tick_diviso_init function.
+ xtensa_vectors.S Replaced exit macros.
+ tx*.h Modified comment(s).
+ tx*.c Modified comment(s).
+ tx*.S Modified comment(s).
+
+06/18/2008 ThreadX Xtensa version 5.2. It includes the following modifications:
+
+ tx_port.h Added "extern" to the interrupt control
+ function prototype, and modified
+ version ID string.
+ tx_api_asm.h Fixed bug whereby tx_thread_cp_state
+ was off by 1 word and overlapped
+ tx_thread_name if TX_THREAD_SAFE_CLIB
+ was not defined.
+ xtensa_vectors.S Strengthened syncs for strict ISA
+ conformance. Aligned exit dispatchers.
+ tx*.h Modified comment(s).
+ tx*.c Modified comment(s).
+ tx*.S Modified comment(s).
+
+04/02/2007 ThreadX Xtensa version 5.1. This release adds minor enhancements
+ and supports evaluation boards via a new board independent "XTBSP"
+ API (allowing ThreadX to take advantage of any supported board)
+ and deprecates board-specific code for the obsolete XT2000.
+ It includes the following modifications:
+
+ tx_port.h Co-proc check uses XCHAL_CP_NUM,
+ deprecated XT_XT2000 option,
+ included tx_user.h first, and
+ made TX_MAX_PRIORITIES visible
+ to assembler code.
+ tx_xtensa_stack_error_handler.c Accessed board's display via API
+ and deprecated XT_XT2000 option.
+ tx_initialize_low_level.S Co-proc check uses XCHAL_CP_NUM,
+ modified timer setup and
+ supported TX_NO_TIMER.
+ tx_thread_context_restore.S Co-proc check uses XCHAL_CP_NUM.
+ tx_thread_schedule.S Co-proc check uses XCHAL_CP_NUM.
+ tx_thread_system_return.S Co-proc check uses XCHAL_CP_NUM.
+ tx_timer_interrupt.S Use tick divisor computed via
+ API and support TX_NO_TIMER.
+ xtensa_context.h Co-proc check uses XCHAL_CP_NUM.
+ xtensa_context.S Co-proc check uses XCHAL_CP_NUM.
+ xtensa_init.c Added new initialization code to
+ set tick timer using board API.
+ xtensa_rtos.h Allowed tx_user.h macros to
+ affect Xtensa-generic macros and
+ supported TX_NO_TIMER.
+ xtensa_timer.h Updated timer configuration
+ logic and supported TX_NO_TIMER.
+ xtensa_vectors.S Co-proc check uses XCHAL_CP_NUM
+ and updated logic for long jumps
+ and supported TX_NO_TIMER.
+ tx*.h Modified comment(s).
+ tx*.c Modified comment(s).
+ tx*.S Modified comment(s).
+
+10/10/2006 Initial ThreadX version for Xtensa configurable processors
+ and Diamond pre-configured processors using Xtensa Tools.
+
+
+Copyright(c) 1996-2020 Microsoft Corporation
+
+
+https://azure.com/rtos
+
diff --git a/ports/xtensa/xcc/src/tx_clib_lock.c b/ports/xtensa/xcc/src/tx_clib_lock.c
new file mode 100644
index 00000000..072cbd52
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_clib_lock.c
@@ -0,0 +1,406 @@
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This file contains the interface functions to provide thread-safe */
+/* operation of the C library. Both newlib and the Xtensa C Library */
+/* are supported. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+#include "tx_api.h" /* TX_THREAD_SAFE_CLIB may be defined by tx_port.h */
+#include "tx_thread.h"
+#include "tx_initialize.h"
+
+/* Xtensa specific */
+#include
+
+#ifdef TX_THREAD_SAFE_CLIB /* this file is only needed if using C lib */
+
+#include
+#include
+#include
+#include
+
+
+#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+
+#include
+
+/* NOTE: should have been declared in reent.h... */
+extern void _wrapup_reent(struct _reent * ptr);
+
+/* Mutex used for all C library protection */
+TX_MUTEX clib_lock_mutex;
+
+
+/**************************************************************************/
+/* __malloc_lock - called by the malloc() family of routines when they */
+/* need to lock the memory pool. A call to malloc() may call this */
+/* function recursively. */
+/**************************************************************************/
+void
+__malloc_lock (struct _reent * ptr)
+{
+ if (_tx_thread_system_state != TX_INITIALIZE_IS_FINISHED) {
+ return;
+ }
+
+ tx_mutex_get (&clib_lock_mutex, TX_WAIT_FOREVER);
+}
+
+/**************************************************************************/
+/* __malloc_unlock - called by the malloc() family of routines when */
+/* need to unlock the memory pool. */
+/**************************************************************************/
+void
+__malloc_unlock (struct _reent * ptr)
+{
+ if (_tx_thread_system_state != TX_INITIALIZE_IS_FINISHED) {
+ return;
+ }
+
+#ifndef THREADX_TESTSUITE /* see THREADX_TESTSUITE comments below */
+ tx_mutex_prioritize (&clib_lock_mutex); /* is this at all necessary? */
+#endif
+ tx_mutex_put (&clib_lock_mutex);
+}
+
+
+/**************************************************************************/
+/* __env_lock - called by the setenv() family of routines when they */
+/* need to modify the environment. A call to setenv() may call this */
+/* function recursively. */
+/**************************************************************************/
+void
+__env_lock (struct _reent * ptr)
+{
+ if (_tx_thread_system_state != TX_INITIALIZE_IS_FINISHED) {
+ return;
+ }
+
+ tx_mutex_get (&clib_lock_mutex, TX_WAIT_FOREVER);
+}
+
+/**************************************************************************/
+/* __env_unlock - called by the setenv() family of routines when they */
+/* need to unlock the environment. */
+/**************************************************************************/
+void
+__env_unlock (struct _reent * ptr)
+{
+ if (_tx_thread_system_state != TX_INITIALIZE_IS_FINISHED) {
+ return;
+ }
+
+ tx_mutex_prioritize (&clib_lock_mutex);
+ tx_mutex_put (&clib_lock_mutex);
+}
+
+#endif /* XSHAL_CLIB == XTHAL_CLIB_NEWLIB */
+
+#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
+
+#include
+#include
+
+#define XT_NUM_CLIB_LOCKS (_MAX_LOCK + FOPEN_MAX)
+
+typedef TX_MUTEX * _Rmtx;
+
+static TX_MUTEX xclib_locks[XT_NUM_CLIB_LOCKS];
+static uint32_t lcnt;
+
+/* Override this and set to nonzero to enable locking. */
+int32_t _xclib_use_mt = 1;
+
+
+/**************************************************************************/
+/* _Mtxinit - initialize a lock. Called once for each lock. */
+/**************************************************************************/
+void
+_Mtxinit (_Rmtx * mtx)
+{
+ TX_MUTEX * lock;
+
+ if (lcnt >= XT_NUM_CLIB_LOCKS) {
+ /* Fatal error */
+ }
+
+ lock = &(xclib_locks[lcnt]);
+ lcnt++;
+
+ /* See notes for newlib case below. */
+#ifdef THREADX_TESTSUITE
+ tx_mutex_create (lock, "Clib lock", 0);
+#else
+ tx_mutex_create (lock, "Clib lock", TX_INHERIT);
+#endif
+
+ *mtx = lock;
+}
+
+/**************************************************************************/
+/* _Mtxdst - destroy a lock. Called once for each lock. */
+/**************************************************************************/
+void
+_Mtxdst (_Rmtx * mtx)
+{
+ if ((mtx) && (*mtx)) {
+ tx_mutex_delete (*mtx);
+ }
+}
+
+/**************************************************************************/
+/* _Mtxlock - acquire lock. */
+/**************************************************************************/
+void
+_Mtxlock (_Rmtx * mtx)
+{
+ if ((mtx) && (*mtx)) {
+ tx_mutex_get (*mtx, TX_WAIT_FOREVER);
+ }
+}
+
+/**************************************************************************/
+/* _Mtxunlock - release a lock. */
+/**************************************************************************/
+void
+_Mtxunlock (_Rmtx * mtx)
+{
+ if ((mtx) && (*mtx)) {
+ tx_mutex_put (*mtx);
+ }
+}
+
+#endif /* XSHAL_CLIB == XTHAL_CLIB_XCLIB */
+
+
+/**************************************************************************/
+/* _sbrk_r - heap allocator. This function is called when the memory */
+/* allocator needs a new chunk of memory. */
+/* The bounds of the heap area are global variables so that customer */
+/* startup code can easily override them if needed. */
+/* */
+/* _tx_clib_heap_start is the start of memory assigned to the heap */
+/* or 0 (NULL) if no memory is assigned (in */
+/* that case all calls to malloc will fail). */
+/* */
+/* _tx_clib_heap_end is the end of memory assigned to the heap */
+/* or 0 (NULL) if no memory is assigned. If a */
+/* nonzero start value is set then a nonzero */
+/* end value must be set. */
+/**************************************************************************/
+
+char * _tx_clib_heap_start = NULL;
+char * _tx_clib_heap_end = NULL;
+
+void *
+_sbrk_r (struct _reent * reent, int32_t incr)
+{
+ static char * heap_ptr;
+ char * new_heap_ptr;
+ char * alloc_ptr;
+
+ /* The heap is bound by _tx_clib_heap_{start,end}. */
+ if (heap_ptr == NULL) {
+ heap_ptr = _tx_clib_heap_start;
+ }
+
+ new_heap_ptr = heap_ptr + incr;
+ if ((heap_ptr == NULL) || /* no heap */
+ (new_heap_ptr >= _tx_clib_heap_end) || /* heap exhausted */
+ (new_heap_ptr < heap_ptr)) { /* wraparound */
+ reent->_errno = ENOMEM;
+ return (void *) -1;
+ }
+
+ alloc_ptr = heap_ptr;
+ heap_ptr = new_heap_ptr;
+ return (void *) alloc_ptr;
+}
+
+
+/**************************************************************************/
+/* _tx_clib_init - initialize C library thread safety support. */
+/* Called by _tx_initialize_low_level(). */
+/**************************************************************************/
+void
+_tx_clib_init (void)
+{
+#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+#ifdef THREADX_TESTSUITE
+ /* Priority inheritance causes printf() (which calls malloc()
+ which calls __malloc_unlock() which calls tx_mutex_put()
+ which calls _tx_mutex_priority_change() if TX_INHERIT is set)
+ which causes the task to suspend and resume which sometimes
+ changes execution order in the very sensitive testsuite
+ and makes it fail. So, for the testsuite, don't request
+ priority inheritance (it doesn't need it in any case). */
+ tx_mutex_create (&clib_lock_mutex, "Clib lock", 0);
+#else
+ tx_mutex_create (&clib_lock_mutex, "Clib lock", TX_INHERIT);
+#endif
+#endif /* NEWLIB */
+
+#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ /* Nothing. */
+#endif /* XCLIB */
+}
+
+
+/**************************************************************************/
+/* _tx_clib_reent_init - initialize C library thread reent structure. */
+/* Called by tx_thread_create() to init per-thread C library state. */
+/**************************************************************************/
+void
+_tx_clib_reent_init (TX_THREAD * thread_ptr)
+{
+ if (thread_ptr == NULL) {
+ /* Should never happen */
+ return;
+ }
+
+#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+ struct _reent * reent = &(thread_ptr->tx_thread_clib_reent);
+
+ memset (reent, 0, sizeof(struct _reent));
+ _REENT_INIT_PTR (reent);
+ thread_ptr->tx_thread_clib_ptr = reent;
+#endif
+
+#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ thread_ptr->tx_thread_clib_ptr = &(thread_ptr->tx_thread_clib_reent);
+ _init_reent (thread_ptr->tx_thread_clib_ptr);
+#endif
+}
+
+
+/**************************************************************************/
+/* _tx_clib_reent_cleanup - clean up C library thread reent structure. */
+/* Called by tx_thread_delete() to clean up per-thread C library state */
+/* and free any allocated memory (partial = 0). */
+/* Called by tx_thread_shell_entry and tx_thread_terminate to perform */
+/* "atexit" processing and clean up stdio, but leaving the rest of the */
+/* structure intact so the thread can be restarted (partial = 1). */
+/**************************************************************************/
+void
+_tx_clib_reent_cleanup (TX_THREAD * thread_ptr, int32_t partial)
+{
+#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+ struct _reent * reent = &(thread_ptr->tx_thread_clib_reent);
+ FILE * fp = &(reent->__sf[0]);
+ int32_t i;
+
+ /* Avoid closing stdin,stdout,stderr so other threads can still use them. */
+ for (i = 0; i < 3; i++) {
+ fp->_close = NULL;
+ fp++;
+ }
+
+ if (partial != 0) {
+ /* Perform "atexit" processing and clean up stdio. */
+ _wrapup_reent (reent);
+ }
+ else {
+ /* Free all the heap memory allocated in the reent structure.
+ ThreadX requires that the thread has either exited or been
+ terminated before it can be deleted so we can assume that
+ _wrapup_reent has already been called for this thread. */
+ _reclaim_reent (reent);
+ }
+#endif
+
+#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ /* Unused, keep compiler happy */
+ (void) partial;
+
+ /* File handle table is global; no allocated memory in struct. */
+ thread_ptr->tx_thread_clib_ptr = 0;
+#endif
+}
+
+
+/**************************************************************************/
+/* _xt_wrapper - thread wrapper to handle C library init/cleanup. */
+/* If C library thread safety is enabled, every thread is invoked */
+/* via this wrapper in order to handle thread context setup/cleanup. */
+/**************************************************************************/
+void
+_xt_thread_wrapper (ULONG arg)
+{
+ TX_INTERRUPT_SAVE_AREA
+ TX_THREAD * thread_ptr = _tx_thread_current_ptr;
+
+ /* No use for this parameter */
+ (void) arg;
+
+ /* Init the C library thread context */
+ _tx_clib_reent_init (thread_ptr);
+
+ /* Disable interrupts around the global context ptr update */
+ TX_DISABLE
+
+#if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+ _impure_ptr = thread_ptr->tx_thread_clib_ptr;
+#endif
+#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ _reent_ptr = thread_ptr->tx_thread_clib_ptr;
+#endif
+
+ TX_RESTORE
+
+ /* Call actual thread entry point */
+ (thread_ptr->tx_real_thread_entry)(thread_ptr->tx_thread_entry_parameter);
+
+ /* Clean up C library thread context */
+ _tx_clib_reent_cleanup(thread_ptr, 1);
+ _tx_clib_reent_cleanup(thread_ptr, 0);
+}
+
+
+/**************************************************************************/
+/* _tx_clib_thread_setup - Xtensa-specific thread setup actions. */
+/* This function will be called only if thread safe C library usage */
+/* is enabled. It inserts the wrapper as the thread entry point and */
+/* saves the actual entry point for later use. */
+/**************************************************************************/
+void
+_tx_clib_thread_setup (TX_THREAD * thread_ptr)
+{
+ thread_ptr->tx_real_thread_entry = thread_ptr->tx_thread_entry;
+ thread_ptr->tx_thread_entry = &(_xt_thread_wrapper);
+}
+
+#endif /* TX_THREAD_SAFE_CLIB */
+
diff --git a/ports/xtensa/xcc/src/tx_initialize_low_level.c b/ports/xtensa/xcc/src/tx_initialize_low_level.c
new file mode 100644
index 00000000..d7082db0
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_initialize_low_level.c
@@ -0,0 +1,187 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+
+#include "tx_api.h"
+#include "tx_port.h"
+#include "xtensa_api.h"
+
+#if XCHAL_HAVE_ISL || XCHAL_HAVE_KSL || XCHAL_HAVE_PSL
+#include
+#endif
+
+
+#if XCHAL_HAVE_XEA3
+int32_t xt_sw_intnum = -1;
+int32_t xt_timer_intnum = -1;
+#endif
+
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is responsible for any low-level processor */
+/* initialization, including setting up interrupt vectors, setting */
+/* up a periodic timer interrupt source, saving the system stack */
+/* pointer for use in ISR processing later, and finding the first */
+/* available RAM memory address for tx_application_define. */
+/* It also sets the default heap region for the optional C library. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+VOID _tx_initialize_low_level(VOID)
+{
+ extern char _xt_interrupt_stack_top;
+ extern void _tx_timer_interrupt(void *);
+ extern void * _tx_thread_system_stack_ptr;
+ extern void * _tx_initialize_unused_memory;
+ extern char _end;
+
+ #ifdef TX_THREAD_SAFE_CLIB
+ extern char __stack;
+ extern void _tx_clib_init(void);
+ #endif
+
+ #if XCHAL_CP_NUM > 0
+ extern void _xt_coproc_init(void);
+ extern void _xt_coproc_exc(XtExcFrame * fp);
+ #endif
+
+ #ifdef TX_ENABLE_STACK_CHECKING
+ extern VOID _tx_xtensa_stack_error_handler(TX_THREAD * thread);
+ #endif
+
+ #if XCHAL_HAVE_XEA3
+ extern void xt_sched_handler(void * arg);
+ int32_t i;
+ #endif
+
+ TX_INTERRUPT_SAVE_AREA
+
+ /* Disable interrupts - don't want any that interact with ThreadX yet. */
+ TX_DISABLE
+
+ /*
+ Disable stack limit checking if present. Whatever was set up earlier
+ is not going to work for us.
+ */
+#if XCHAL_HAVE_KSL
+ XT_WSR_KSL(0);
+#endif
+#if XCHAL_HAVE_ISL
+ XT_WSR_ISL(0);
+#endif
+
+ /* Save the system stack pointer. */
+ _tx_thread_system_stack_ptr = &(_xt_interrupt_stack_top);
+
+ /* Save the first available memory address. */
+ _tx_initialize_unused_memory = (void *)(((UINT)&_end + 15) & ~0xF);
+
+ #ifdef TX_THREAD_SAFE_CLIB
+ /*
+ Pre-allocate default memory region for the C library heap.
+ Bisect the region from first available memory to end of system memory,
+ align to 16 byte boundary, and allocate the heap in the upper half.
+ */
+ _tx_clib_heap_end = &(__stack);
+ _tx_clib_heap_start =
+ (void *)(((UINT)_tx_initialize_unused_memory/2 + (UINT)_tx_clib_heap_end/2) & ~0xF);
+ #endif
+
+ #if XCHAL_CP_NUM > 0
+ /*
+ Initialize co-processor management for threads. Leave CPENABLE alone.
+ This is called from a normal Xtensa single-threaded run-time environment
+ before multi-threading has commenced. All co-processors are enabled.
+ It is important NOT to clear CPENABLE yet because tx_application_define()
+ is user code which might use a co-processor. The co-processor exception
+ handler does not expect to be called outside a thread.
+ */
+ _xt_coproc_init();
+
+ #if XCHAL_HAVE_XEA3
+ /* Install the coprocessor exception handler. */
+ xt_set_exception_handler(EXCCAUSE_CP_DISABLED, _xt_coproc_exc);
+ #endif
+ #endif
+
+ #if XCHAL_HAVE_XEA3
+ /* Select a software interrupt to use for scheduling. */
+ for (i = 0; i < XCHAL_NUM_INTERRUPTS; i++) {
+ if ((Xthal_inttype[i] == XTHAL_INTTYPE_SOFTWARE) && (Xthal_intlevel[i] == 1)) {
+ xt_sw_intnum = i;
+ break;
+ }
+ }
+
+ if (xt_sw_intnum == -1) {
+ __asm__ volatile ("break 1, 1");
+ }
+
+ /* Set the interrupt handler and enable the interrupt. */
+ xt_set_interrupt_handler(xt_sw_intnum, xt_sched_handler, 0);
+ xt_interrupt_enable(xt_sw_intnum);
+ #endif
+
+ #ifndef TX_NO_TIMER
+
+ /* Compute tick divisor if clock freq is not compile-time constant. */
+ #ifndef XT_CLOCK_FREQ
+ _xt_tick_divisor_init();
+ #endif
+
+ /* Set up the periodic tick timer (assume enough time to complete init). */
+ #ifdef XT_CLOCK_FREQ
+ XT_WSR_CCOMPARE(XT_RSR_CCOUNT() + XT_TICK_DIVISOR);
+ #else
+ XT_WSR_CCOMPARE(XT_RSR_CCOUNT() + _xt_tick_divisor);
+ #endif
+
+ #if XCHAL_HAVE_XEA3
+ xt_timer_intnum = XT_TIMER_INTNUM;
+ xt_set_interrupt_handler(xt_timer_intnum, _tx_timer_interrupt, 0);
+ #endif
+
+ /* Enable the timer interrupt at the device level. */
+ xt_interrupt_enable(XT_TIMER_INTNUM);
+
+ #endif /* TX_NO_TIMER */
+
+ /* Initialize C library thread safety support. */
+ #ifdef TX_THREAD_SAFE_CLIB
+ _tx_clib_init();
+ #endif
+
+ /* Install stack overflow notification callback. */
+ #ifdef TX_ENABLE_STACK_CHECKING
+ tx_thread_stack_error_notify(_tx_xtensa_stack_error_handler);
+ #endif
+}
+
diff --git a/ports/xtensa/xcc/src/tx_thread_context_restore.S b/ports/xtensa/xcc/src/tx_thread_context_restore.S
new file mode 100644
index 00000000..aa628751
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_context_restore.S
@@ -0,0 +1,216 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+
+#if XCHAL_HAVE_XEA2
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function restores the interrupt context if it is processing a */
+/* nested interrupt. If not, it returns to the interrupt thread if no */
+/* preemption is necessary. Otherwise, if preemption is necessary or */
+/* if no thread was running, the function returns to the scheduler. */
+/* */
+/* RELEASE HISTORY */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_thread_context_restore(VOID)
+// {
+ .globl _tx_thread_context_restore
+ .type _tx_thread_context_restore,@function
+ .align 4
+_tx_thread_context_restore:
+
+ /*
+ Please note: Control flow might seem strange. This is because it has been
+ optimized to avoid taken branches in the longest normal path (the critical
+ one for worst-case latency), presumed to be a non-nested interrupt that
+ preempts) and to hide pipeline interlock cycles where possible.
+ */
+
+ /* Lockout interrupts. */
+ XT_INTS_DISABLE(a0)
+
+ #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the ISR exit function to indicate an ISR is complete. */
+ #ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_execution_isr_exit
+ #else
+ call8 _tx_execution_isr_exit
+ #endif
+ #endif
+
+ /* Determine if interrupts are nested. */
+ // if (--_tx_thread_system_state)
+ // {
+
+ movi a2, _tx_thread_system_state /* a2 = & interrupt nesting count */
+ l32i a3, a2, 0 /* decrement interrupt nesting count */
+ addi a3, a3, -1
+ s32i a3, a2, 0
+ bnez a3, .L_tx_thread_nested_restore
+
+ // }
+
+.Ln_tx_thread_not_nested_restore:
+
+ /* Determine if a thread was interrupted and no preemption is required. */
+ // else if (((_tx_thread_current_ptr)
+ // && (_tx_thread_current_ptr == _tx_thread_execute_ptr))
+ // || (_tx_thread_preempt_disable))
+ // {
+
+ movi a0, _tx_thread_current_ptr /* a0 = &_tx_thread_current_ptr */
+ l32i a2, a0, 0 /* a2 = _tx_thread_current_ptr (old) */
+ movi a3, _tx_thread_execute_ptr
+ beqz a2, .L_tx_thread_idle_system_restore
+
+ l32i a3, a3, 0 /* a3 = _tx_thread_execute_ptr (new) */
+ beq a3, a2, .L_tx_thread_no_preempt_restore
+
+ movi a3, _tx_thread_preempt_disable
+ l32i a3, a3, 0 /* a3 = _tx_thread_preempt_disable */
+
+ // /* the no-preempt case has moved down so we fall-thru to preempt */
+ bgei a3, 1, .L_tx_thread_no_preempt_restore
+
+ // }
+ // else
+ // {
+
+.Ln_tx_thread_preempt_restore:
+
+ /* Save remaining context on the thread's stack. */
+ l32i a3, a2, tx_thread_stack_ptr /* a3 = thread's stack ptr */
+
+ /* Store standard preserved registers. */
+ /*
+ Call0 ABI callee-saved regs a12-15 need to be saved before preemption.
+ However a12-13 were saved for scratch by _tx_thread_context_save().
+ */
+ #ifdef __XTENSA_CALL0_ABI__ /* Call0: now save callee-save regs */
+ s32i a14, a3, XT_STK_A14
+ s32i a15, a3, XT_STK_A15
+ #endif
+
+ /* Save the remaining time-slice and disable it. */
+ // if (_tx_timer_time_slice)
+ // {
+ movi a3, _tx_timer_time_slice /* a3 = &_tx_timer_time_slice */
+ l32i a4, a3, 0 /* a4 = _tx_timer_time_slice */
+ beqz a4, .L_tx_thread_dont_save_ts
+
+ // _tx_thread_current_ptr -> tx_thread_time_slice
+ // = _tx_timer_time_slice;
+ // _tx_timer_time_slice = 0; */
+ s32i a4, a2, tx_thread_time_slice
+ movi a4, 0
+ s32i a4, a3, 0
+
+ // }
+
+.L_tx_thread_dont_save_ts:
+
+ /* Clear the current task pointer. */
+ // _tx_thread_current_ptr = TX_NULL;
+ s32i a4, a0, 0 /* a4 == 0 == TX_NULL */
+
+ #if XCHAL_CP_NUM > 0
+ /* Save CPENABLE in thread's co-processor save area, and clear CPENABLE. */
+ rsr a3, CPENABLE
+ s16i a3, a2, tx_thread_cp_state + XT_CPENABLE
+ wsr a4, CPENABLE /* disable all co-processors */
+ #endif
+
+.L_tx_thread_idle_system_restore:
+
+ /*
+ Return via the scheduler.
+ Scheduler returns eventually to this function's caller as if called by it.
+ At this point we are still on the system stack.
+ */
+ // _tx_thread_schedule();
+ call0 _tx_thread_schedule /* never returns here */
+
+ // }
+
+ /* Flow never falls through here. */
+
+.L_tx_thread_no_preempt_restore:
+
+ /* Restore interrupted thread. */
+
+ /* Pickup the saved stack pointer. */
+ // SP = _tx_thread_current_ptr -> tx_thread_stack_ptr;
+ l32i sp, a2, tx_thread_stack_ptr
+
+.L_tx_thread_nested_restore:
+
+ /* Recover the saved context and return to the point of interrupt. */
+
+ call0 _xt_context_restore
+
+ /*
+ Must return via the exit dispatcher corresponding to the entrypoint
+ from which this was called. Interruptee's A0, A1, PS, PC are restored
+ and the interrupt stack frame is deallocated in the exit dispatcher.
+ At this point we are on the thread's stack.
+ */
+ l32i a0, sp, XT_STK_EXIT
+ ret
+
+// }
+
+#endif /* XCHAL_HAVE_XEA2 */
+
diff --git a/ports/xtensa/xcc/src/tx_thread_context_save.S b/ports/xtensa/xcc/src/tx_thread_context_save.S
new file mode 100644
index 00000000..4025ea66
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_context_save.S
@@ -0,0 +1,157 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+
+#if XCHAL_HAVE_XEA2
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function saves the context of an executing thread in the */
+/* beginning of interrupt processing. The function also ensures that */
+/* the system stack is used upon return to the calling ISR. */
+/* */
+/* Interrupts remain disabled and no exceptions are triggered! */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_thread_context_save(VOID)
+// {
+ .globl _tx_thread_context_save
+ .type _tx_thread_context_save,@function
+ .align 4
+_tx_thread_context_save:
+
+ /*
+ Please note: Control flow might seem strange. This is because it has been
+ optimized to avoid taken branches in the longest normal path (the critical
+ one for worst-case latency), presumed to be a non-nested interrupt and
+ non-idle) and to hide pipeline interlock cycles where possible.
+ */
+
+ /*
+ Save a couple of scratch regs to work with that are preserved over the
+ call to _xt_context_save. The latter assumes the interruptee's values
+ of these are already saved and these regs contain different data to be
+ preserved, so doesn't save them in the stack frame, and thereby requires
+ that its caller have already saved them in the interrupt stack frame.
+ We end up with a12 = return address, a13 and a0 are scratch.
+ */
+ s32i a12, sp, XT_STK_A12
+ s32i a13, sp, XT_STK_A13
+
+ /* Check for a nested interrupt condition and increment nesting count. */
+ // if (_tx_thread_system_state++)
+ // {
+ movi a13, _tx_thread_system_state /* a13 = & interrupt nesting count */
+ mov a12, a0 /* a12 = save ret addr (free a0) */
+ l32i a0, a13, 0 /* increment interrupt nesting count */
+ addi a0, a0, 1
+ s32i a0, a13, 0
+ bnei a0, 1, .L_tx_thread_nested_save /* was !=0 before increment? */
+
+ // }
+
+.Ln_tx_thread_not_nested_save:
+
+ /* Otherwise, not nested, check to see if a thread was running. */
+ // else
+ // {
+ // if (_tx_thread_current_ptr)
+ // {
+ movi a0, _tx_thread_current_ptr
+ l32i a13, a0, 0 /* a13 = current thread ctrl blk */
+ beqz a13, .L_tx_thread_idle_system_save
+
+ /* Save the rest of the interrupted context. */
+ call0 _xt_context_save
+
+ /* Save the current stack pointer in the thread's control block. */
+ // _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+ s32i sp, a13, tx_thread_stack_ptr
+
+ // }
+ /* Switch to the system stack and return to ISR. */
+
+.L_tx_thread_idle_system_save:
+
+ /*
+ If interrupted in the idle state, it's not necessary to save any context.
+ But even in the idle case where we are already on the system stack, it is
+ necessary to reset the (system) stack pointer so a series of consecutive
+ interrupts in the idle state do not keep moving the SP downward.
+ */
+
+ // sp = _tx_thread_system_stack_ptr;
+ movi a13, _tx_thread_system_stack_ptr
+ mov a0, a12 /* retrieve return address */
+ l32i sp, a13, 0
+
+ ret
+ // }
+
+.L_tx_thread_nested_save:
+ /* Nested interrupt condition. */
+ /* Save the rest of the interrupted context and return to ISR. */
+ call0 _xt_context_save
+
+ mov a0, a12 /* retrieve return address */
+ ret
+
+// }
+
+#endif /* XCHAL_HAVE_XEA2 */
+
diff --git a/ports/xtensa/xcc/src/tx_thread_interrupt_control.c b/ports/xtensa/xcc/src/tx_thread_interrupt_control.c
new file mode 100644
index 00000000..1a9d42c3
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_interrupt_control.c
@@ -0,0 +1,81 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "tx_api.h"
+#include "xtensa_rtos.h"
+
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is responsible for changing the interrupt lockout */
+/* posture of the system. */
+/* NOTE: In earlier versions this was implemented in assembly. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+UINT _tx_thread_interrupt_control(UINT new_posture)
+{
+#if XCHAL_HAVE_XEA2
+ UINT ret = XT_RSIL(15);
+
+ XT_WSR_PS((ret & ~0xF) | (new_posture & 0xF));
+ XT_RSYNC();
+ return ret & 0xF;
+#else
+ UINT ret = xthal_disable_interrupts();
+
+ xthal_restore_interrupts(new_posture);
+ return ret;
+#endif
+}
+
diff --git a/ports/xtensa/xcc/src/tx_thread_schedule.S b/ports/xtensa/xcc/src/tx_thread_schedule.S
new file mode 100644
index 00000000..287c3530
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_schedule.S
@@ -0,0 +1,253 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "tx_port.h"
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function waits for a thread control block pointer to appear in */
+/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+/* in the variable, the corresponding thread is resumed. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_thread_schedule(VOID)
+// {
+ .globl _tx_thread_schedule
+ .type _tx_thread_schedule,@function
+ .align 4
+_tx_thread_schedule:
+
+#if XCHAL_HAVE_XEA3
+
+ /* Skip "entry" - nothing to save, never returns. */
+
+ movi a2, PS_STACK_KERNEL | PS_DI /* Set PS.STACK = Kernel and */
+ movi a3, PS_STACK_MASK | PS_DI_MASK /* disable interrupts. */
+ xps a2, a3
+
+#ifdef __XTENSA_CALL0_ABI__
+ mov a15, a1 /* Dispatch code expects a15 = old SP */
+#endif
+
+ movi a0, _xt_dispatch + 3 /* Jump to dispatch code. It will */
+ ret /* check for ready thread or idle */
+ /* and handle accordingly. */
+
+ ill /* Should never get back here. */
+
+#else
+
+ /*
+ Note on Windowed ABI:
+ Callers of this don't expect it to return to them. Most use 'call0'.
+ The only windowed (C) caller is _tx_initialize_kernel_enter().
+ There are no args or results to pass. So we don't really care if the
+ window gets rotated. We can omit the 'entry' altogether and avoid the
+ need for a special "no entry" entrypoint to this function.
+ */
+
+ #ifdef XT_ENABLE_TIMING_TEST_HACK
+ /* For timing_test "TS" numbers. INTERNAL USE ONLY. */
+ /* Always use CALL0. We may be here with windowing disabled. */
+ .extern scheduler_return
+ call0 scheduler_return
+ #endif
+
+ /*
+ Wait for a thread to execute (Idle Loop).
+ First ensure interrupts (except hi-pri) are disabled so result
+ of reading _tx_thread_execute_ptr can't change before testing.
+ While there's no thread ready, enable interrupts and wait in a
+ low power state, then disable interrupts and repeat the test.
+ */
+ // do
+ // {
+ movi a3, _tx_thread_execute_ptr
+.L_tx_thread_schedule_loop: /* Idle Loop. */
+ XT_INTS_DISABLE(a2) /* disable interrupts if not already */
+ l32i a2, a3, 0 /* a2 = _tx_thread_execute_ptr */
+ bnez a2, .L_tx_thread_schedule_ready
+ waiti 0 /* enable interrupts and wait for */
+ /* interrupt in low power state */
+ j .L_tx_thread_schedule_loop
+
+ // }
+ // while(_tx_thread_execute_ptr == TX_NULL);
+
+.L_tx_thread_schedule_ready:
+
+ /* Yes! We have a thread to execute. Lockout interrupts and
+ transfer control to it. Interrupts are already disabled. */
+
+ /* Setup the current thread pointer. */
+ // _tx_thread_current_ptr = _tx_thread_execute_ptr;
+ movi a3, _tx_thread_current_ptr
+ l32i a0, a2, tx_thread_run_count
+ s32i a2, a3, 0 /* a2 = _tx_thread_current_ptr (TCB) */
+
+ /* Increment the run count for this thread. */
+ // _tx_thread_current_ptr -> tx_thread_run_count++;
+ addi a3, a0, 1
+ movi a0, _tx_timer_time_slice
+ s32i a3, a2, tx_thread_run_count
+
+ /* Setup time-slice, if present. */
+ // _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+ l32i a3, a2, tx_thread_time_slice
+ s32i a3, a0, 0
+
+ #ifdef TX_THREAD_SAFE_CLIB
+ // Load library-specific global context ptr address. */
+
+ #if XSHAL_CLIB == XTHAL_CLIB_NEWLIB
+ movi a0, _impure_ptr
+ #elif XSHAL_CLIB == XTHAL_CLIB_XCLIB
+ movi a0, _reent_ptr
+ #else
+ #error TX_THREAD_SAFE_CLIB defined with unsupported C library.
+ #endif
+
+ l32i a3, a2, tx_thread_clib_ptr
+ s32i a3, a0, 0 /* point to thread's reent struct */
+ #endif
+
+ /* Switch to the thread's stack. */
+ // SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+ l32i sp, a2, tx_thread_stack_ptr
+
+ #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the thread entry function to indicate the thread is executing. */
+ #ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_execution_thread_enter
+ #else
+ call8 _tx_execution_thread_enter
+ #endif
+ #endif
+
+ /* Determine if an interrupt frame or a synchronous task suspension frame
+ is present. */
+ l32i a3, a2, tx_thread_solicited
+ bnez a3, .L_tx_thread_synch_return
+
+.Ln_tx_thread_asynch_return:
+
+ #if XCHAL_CP_NUM > 0
+ /* Restore thread's CPENABLE (enable co-processors this thread owns). */
+ l16ui a3, a2, tx_thread_cp_state + XT_CPENABLE
+ wsr a3, CPENABLE
+ #endif
+
+ /* Here we return from unsolicited entry with an interrupt stack frame. */
+ call0 _xt_context_restore
+
+ /* In Call0 ABI, restore callee-saved regs (A12, A13 already restored). */
+ #ifdef __XTENSA_CALL0_ABI__
+ l32i a14, sp, XT_STK_A14
+ l32i a15, sp, XT_STK_A15
+ #endif
+
+ #if XCHAL_CP_NUM > 0
+ rsync /* ensure wsr.CPENABLE has completed */
+ #endif
+
+ /*
+ This does not return to its caller, but to the selected thread.
+ Must return via the exit dispatcher corresponding to the entrypoint
+ from which this was called. Interruptee's A0, A1, PS, PC are restored
+ and the interrupt stack frame is deallocated in the exit dispatcher.
+ */
+ l32i a0, sp, XT_STK_EXIT
+ ret
+
+.L_tx_thread_synch_return:
+
+ /* Here we return from a solicited entry with a solicited stack frame. */
+ movi a0, TX_FALSE
+ l32i a3, sp, XT_STK_PS
+ s32i a0, a2, tx_thread_solicited
+
+ #ifdef __XTENSA_CALL0_ABI__
+ l32i a12, sp, XT_STK_A12
+ l32i a13, sp, XT_STK_A13
+ l32i a14, sp, XT_STK_A14
+ l32i a15, sp, XT_STK_A15
+ #endif
+
+ l32i a0, sp, XT_STK_PC /* return address */
+
+ #if XCHAL_CP_NUM > 0
+ /* CPENABLE should already be clear (it was cleared on entry to kernel). */
+ rsync /* ensure wsr.CPENABLE has completed */
+ #endif
+
+ wsr a3, PS /* no need to sync PS, delay is OK */
+
+ /* This does not return to its caller, but to the selected thread. */
+ #ifdef __XTENSA_CALL0_ABI__
+ /* 'addi sp, sp, imm' could turn into 'addmi, addi' sequence and make */
+ /* the sp briefly point to an illegal stack location. Avoid that. */
+ addi a2, sp, XT_STK_FRMSZ
+ mov sp, a2
+ ret
+ #else
+ retw
+ #endif
+
+#endif /* XCHAL_HAVE_XEA3 */
+// }
+
diff --git a/ports/xtensa/xcc/src/tx_thread_stack_build.S b/ports/xtensa/xcc/src/tx_thread_stack_build.S
new file mode 100644
index 00000000..688e947d
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_stack_build.S
@@ -0,0 +1,158 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function builds a stack frame on the supplied thread's stack. */
+/* The stack frame looks like an interrupt frame or a solicited frame */
+/* depending on the exception architecture of the target hardware. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+// {
+ .globl _tx_thread_stack_build
+ .type _tx_thread_stack_build,@function
+ .align 4
+_tx_thread_stack_build:
+
+ ENTRY0
+
+ /* Get logical base of stack area (top). */
+ l32i a5, a2, tx_thread_stack_end /* get top-1 of stack area */
+ addi a5, a5, 1 /* undo the -1 */
+ srli a5, a5, 4 /* force 16-byte alignment */
+ slli a5, a5, 4 /* a5 = post-dispatch SP (frame top) */
+
+ /* Allocate space for the frame (frame size is already 16-byte aligned). */
+ addi a4, a5, -XT_STK_FRMSZ /* a4 = pre-dispatch SP (frame base) */
+
+ /* Set the thread's SP. */
+ s32i a4, a2, tx_thread_stack_ptr
+
+#if !XCHAL_HAVE_XEA2
+ addi a4, a4, XT_STK_XTRA_SZ /* a4 = base of exception frame */
+#endif
+
+ /* Clear the entire frame. (XEA3: only exception frame) */
+ movi a6, 0 /* a6 = 0 */
+ mov a7, a4 /* a7 = ptr to current word */
+1: s32i a6, a7, 0 /* clear current word */
+ addi a7, a7, 4 /* point to next word */
+ bltu a7, a5, 1b /* repeat until frame top */
+
+#if XCHAL_HAVE_XEA2
+ s32i a5, a4, XT_STK_A1 /* save post-dispatch SP in frame */
+#endif
+
+ /* Indicate a solicited or interrupted stack frame. */
+#if XCHAL_HAVE_XEA2
+ movi a7, 0 /* interrupted */
+#else
+ movi a7, 0 /* solicited */
+#endif
+ s32i a7, a2, tx_thread_solicited
+
+ /*
+ Terminate GDB backtrace in this thread at the "return function" by ensuring
+ it's A0 == 0. Since frame was cleared, don't need to do this explicitly.
+ s32i a6, a4, XT_STK_A0
+ */
+
+ /* Set the return address to the return function. */
+ /* Start thread via user exception exit dispatcher (could use any). */
+#if XCHAL_HAVE_XEA2
+ movi a5, _xt_user_exit
+ s32i a5, a4, XT_STK_EXIT
+#else
+ movi a5, 0
+ s32i a5, a4, XT_STK_ATOMCTL
+#endif
+
+ s32i a3, a4, XT_STK_PC
+
+ /*
+ Set thread's initial PS for C code, all int levels enabled.
+ XEA2: Since we dispatch via level 1 (_xt_user_exit), must set PS.EXCM,
+ which will be cleared by 'rfe' after the dispatcher, to prevent
+ interrupts happening when PS is restored during the exit dispatcher.
+ XEA3: nothing special, other than setting the thread stack type.
+ */
+#if XCHAL_HAVE_XEA2
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a6, PS_UM | PS_EXCM
+ #else
+ movi a6, PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1) /* pretend 'call4' */
+ #endif
+#else
+ movi a6, PS_STACK_FIRSTKER
+#endif
+ s32i a6, a4, XT_STK_PS
+
+#if XCHAL_HAVE_XEA2
+ #ifdef XT_USE_SWPRI
+ /* Set the initial virtual priority mask value to all 1's */
+ movi a3, -1
+ s32i a3, a4, XT_STK_VPRI
+ #endif
+#endif
+
+ RET0
+
+// }
+
diff --git a/ports/xtensa/xcc/src/tx_thread_system_return.S b/ports/xtensa/xcc/src/tx_thread_system_return.S
new file mode 100644
index 00000000..e90109c1
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_thread_system_return.S
@@ -0,0 +1,287 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Thread */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function is target processor specific. It is used to transfer */
+/* control from a thread back to the system. Only a minimal context */
+/* is saved since the compiler assumes temp registers are going to get */
+/* slicked by a function call anyway. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_thread_system_return(VOID)
+// {
+ .globl _tx_thread_system_return
+ .type _tx_thread_system_return,@function
+ .align 4
+_tx_thread_system_return:
+ /*
+ Set up solicited stack frame and save minimal context (including a0).
+ Since this is solicited, no need to save regs compiler doesn't preserve.
+ */
+
+#if XCHAL_HAVE_XEA3
+ #ifdef __XTENSA_CALL0_ABI__
+ addi sp, sp, -16
+ #else
+ entry sp, 48
+ #endif
+ s32i a0, sp, 0 /* save return address */
+#else
+ #ifdef __XTENSA_CALL0_ABI__
+ addi a2, sp, -XT_STK_FRMSZ /* avoid addi/addmi relaxation that */
+ mov sp, a2 /* might temporarily move sp up */
+ #else
+ entry sp, XT_STK_FRMSZ
+ #endif
+#endif
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the thread exit function to indicate the thread is no longer executing. */
+#ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_execution_thread_exit
+#else
+ call8 _tx_execution_thread_exit
+#endif
+#endif
+
+#if XCHAL_HAVE_XEA3
+
+#ifdef __XTENSA_CALL0_ABI__
+
+#else
+ ssai 0
+ spillw /* spill all registers */
+#endif
+
+ /*
+ Save register state into exception frame. This is safe to do with
+ interrupts enabled, but we will have to revert SP to point above
+ the exception frame because that is what the dispatch code expects.
+ Must disable interrupts before that.
+ */
+
+ movi a0, .Lret
+ rsr.ps a2
+ addi sp, sp, -XT_STK_XFRM_SZ
+ s32i a0, sp, XT_STK_PC /* save return PC */
+ s32i a2, sp, XT_STK_PS /* save PS */
+#ifdef __XTENSA_CALL0_ABI__
+ s32i a12, sp, XT_STK_A12 /* callee-saved registers */
+ s32i a13, sp, XT_STK_A13
+ s32i a14, sp, XT_STK_A14
+ s32i a15, sp, XT_STK_A15
+#endif
+
+ movi a2, PS_STACK_KERNEL | PS_DI /* Set PS.STACK = Kernel and */
+ movi a8, PS_STACK_MASK | PS_DI_MASK /* disable interrupts. */
+ xps a2, a8
+
+ movi a3, _tx_thread_current_ptr /* a3 = &_tx_thread_current_ptr */
+ movi a2, TX_TRUE
+ l32i a4, a3, 0 /* a4 = _tx_thread_current_ptr */
+ movi a5, 0
+ s32i a2, a4, tx_thread_solicited /* mark as solicited switch */
+
+#if XCHAL_CP_NUM > 0
+ /* Save coprocessor callee-saved state (if any). At this point CPENABLE */
+ /* should still reflect which CPs were in use (enabled). */
+ call0 _xt_coproc_savecs
+
+ /* Clear CPENABLE and give up all co-procs. */
+ s16i a5, a4, tx_thread_cp_state + XT_CPENABLE
+ wsr a5, CPENABLE /* disable all co-processors */
+#endif
+
+ addi sp, sp, XT_STK_XFRM_SZ /* restore SP */
+ addi a2, sp, -XT_STK_FRMSZ
+ s32i a2, a4, tx_thread_stack_ptr /* Save SP in TCB */
+
+#ifdef __XTENSA_CALL0_ABI__
+ mov a15, sp /* Dispatch code expects a15 = old a1 */
+#endif
+
+ s32i a5, a3, 0 /* Clear _tx_thread_current_ptr */
+
+ movi a0, _xt_dispatch + 3 /* Jump to dispatch code */
+ ret
+
+ /* Execution returns here. Interrupts should be disabled. */
+ /* NOTE: we expect original SP to have been restored. */
+
+ .align 4
+
+.Lret:
+ addi sp, sp, -XT_STK_XFRM_SZ /* Prepare to restore state */
+ l32i a2, sp, XT_STK_PS /* Retrieve PS value */
+#ifdef __XTENSA_CALL0_ABI__
+ l32i a12, sp, XT_STK_A12 /* Callee-saved registers */
+ l32i a13, sp, XT_STK_A13
+ l32i a14, sp, XT_STK_A14
+ l32i a15, sp, XT_STK_A15
+#endif
+ addi sp, sp, XT_STK_XFRM_SZ
+ wsr.ps a2 /* Safe to enable interrupts */
+ rsync
+
+#ifdef __XTENSA_CALL0_ABI__
+ l32i a0, sp, 0
+ addi sp, sp, 16
+ ret
+#else
+ l32i a0, sp, 0
+ retw
+#endif
+
+#else /* XEA1 or XEA2 */
+
+ rsr a2, PS
+ s32i a0, sp, XT_STK_PC
+ s32i a2, sp, XT_STK_PS
+ #ifdef __XTENSA_CALL0_ABI__
+ s32i a12, sp, XT_STK_A12
+ s32i a13, sp, XT_STK_A13
+ s32i a14, sp, XT_STK_A14
+ s32i a15, sp, XT_STK_A15
+ #else
+ /*
+ Spill register windows. Calling xthal_window_spill() causes extra spills and
+ reloads, so we set things up to call the _nw version instead to save cycles.
+ */
+ movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK) // (using a6 ensures any window using this a4..a7 is spilled)
+ mov a4, a0 // save a0
+ and a2, a2, a6 // clear WOE, INTLEVEL
+ addi a2, a2, XCHAL_EXCM_LEVEL // set INTLEVEL
+ wsr a2, PS
+ rsync
+ call0 xthal_window_spill_nw
+ l32i a0, sp, XT_STK_PS
+ wsr a0, PS // Restore PS value
+ rsync
+ #endif
+
+ #if XCHAL_CP_NUM > 0
+ /* Save coprocessor callee-saved state (if any). At this point CPENABLE */
+ /* should still reflect which CPs were in use (enabled). */
+ call0 _xt_coproc_savecs
+ #endif
+
+ /*
+ We do not return directly from this function to its caller.
+ Register usage from here on:
+ a0 = scratch (return address has been saved in stack frame)
+ a1 = stack ptr (thread, then system)
+ a2 = &_tx_thread_current_ptr
+ a3 = _tx_thread_current_ptr (thread control block)
+ a4 = &_tx_timer_time_slice
+ */
+
+ /* Lock out interrupts (except hi-pri). */
+ /* Grab thread control block of current thread. */
+ movi a2, _tx_thread_current_ptr /* a2 = &_tx_thread_current_ptr */
+ XT_INTS_DISABLE(a0)
+ l32i a3, a2, 0 /* a3 points to TCB */
+
+ /* Mark as having solicited entry to kernel (used on exit). */
+ movi a0, TX_TRUE
+ s32i a0, a3, tx_thread_solicited
+
+ /* Save current stack and switch to system stack. */
+ // _tx_thread_current_ptr -> tx_thread_stack_ptr = SP;
+ // SP = _tx_thread_system_stack_ptr;
+ movi a5, _tx_thread_system_stack_ptr /* a5 = & system stack ptr */
+ s32i sp, a3, tx_thread_stack_ptr
+ movi a4, _tx_timer_time_slice /* a4 = &_tx_timer_time_slice */
+ l32i sp, a5, 0 /* sp = system stack ptr */
+
+ /* Determine if the time-slice is active. */
+ // if (_tx_timer_time_slice)
+ // {
+ l32i a0, a4, 0
+ beqz a0, .L_tx_thread_dont_save_ts
+
+ /* Save time-slice for the thread and clear current time-slice. */
+ // _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+ // _tx_timer_time_slice = 0;
+ s32i a0, a3, tx_thread_time_slice
+ movi a0, 0 /* a0 == 0 == TX_NULL */
+ s32i a0, a4, 0
+
+ // }
+
+.L_tx_thread_dont_save_ts:
+
+ /* Clear the current thread pointer. */
+ // _tx_thread_current_ptr = TX_NULL;
+ s32i a0, a2, 0 /* a0 == 0 == TX_NULL */
+
+ #if XCHAL_CP_NUM > 0
+ /* Clear CPENABLE and give up all co-procs. */
+ s16i a0, a3, tx_thread_cp_state + XT_CPENABLE
+ wsr a0, CPENABLE /* disable all co-processors */
+ #endif
+
+ /*
+ Return via the scheduler.
+ Scheduler returns eventually to this function's caller as if called by it.
+ */
+ call0 _tx_thread_schedule /* never returns here */
+
+#endif /* XCHAL_HAVE_XEA3 */
+// }
+
diff --git a/ports/xtensa/xcc/src/tx_timer_interrupt.S b/ports/xtensa/xcc/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..6fcc5d36
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_timer_interrupt.S
@@ -0,0 +1,277 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Timer */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+#include "tx_api_asm.h"
+
+#ifndef TX_NO_TIMER
+
+ .text
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* This function processes the hardware timer interrupt. This */
+/* processing includes incrementing the system clock and checking for */
+/* time slice and/or timer expiration. If either is found, the */
+/* interrupt context save/restore functions are called along with the */
+/* expiration functions. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+// VOID _tx_timer_interrupt(VOID)
+// {
+ .globl _tx_timer_interrupt
+ .type _tx_timer_interrupt,@function
+ .align 4
+_tx_timer_interrupt:
+
+ #ifdef __XTENSA_CALL0_ABI__
+ /* Define local variable spill offsets in stack frame for Call0 ABI. */
+ #define __tx_timer_interrupt_a0 0 /* ENTRY()/RET() saves/restores */
+ #define __tx_timer_interrupt_a2 4 /* preserve a2 */
+ #define __tx_timer_interrupt_a3 8 /* preserve a3 */
+ #endif
+
+ ENTRY(16)
+
+ .globl tx_timer_user_isr
+ .weak tx_timer_user_isr
+ movi a2, tx_timer_user_isr
+ beqz a2, 1f
+ #ifdef __XTENSA_CALL0_ABI__
+ callx0 a2
+ #else
+ callx8 a2
+ #endif
+1:
+
+ /*
+ Xtensa timers work by comparing a cycle counter with a preset value.
+ Once the match occurs an interrupt is generated, and the handler has
+ to set a new cycle count into the comparator. To avoid clock drift
+ due to interrupt latency, the new cycle count is computed from the old,
+ not the time the interrupt was serviced. However if a timer interrupt
+ is ever serviced more than one tick late, it is necessary to process
+ multiple ticks until the new cycle count is in the future, otherwise
+ the next timer interrupt would not occur until after the cycle counter
+ had wrapped (2^32 cycles later).
+
+ do {
+ ticks++;
+ old_ccompare = read_ccompare_i();
+ write_ccompare_i( old_ccompare + divisor );
+ service one tick;
+ diff = read_ccount() - old_ccompare;
+ } while ( diff > divisor );
+ */
+
+.L_tx_timer_catchup:
+
+ /* Increment the system clock. */
+ // _tx_timer_system_clock++;
+ movi a2, _tx_timer_system_clock /* a2 = &_tx_timer_system_clock */
+ l32i a3, a2, 0 /* a3 = _tx_timer_system_clock++ */
+ addi a3, a3, 1
+ s32i a3, a2, 0
+
+ /* Update the timer comparator for the next tick. */
+ #ifdef XT_CLOCK_FREQ
+ movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */
+ #else
+ movi a3, _xt_tick_divisor
+ l32i a2, a3, 0 /* a2 = comparator increment */
+ #endif
+ rsr a3, XT_CCOMPARE /* a3 = old comparator value */
+ add a4, a3, a2 /* a4 = new comparator value */
+ wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */
+ esync
+
+ /* Test for time-slice expiration. */
+ // if (_tx_timer_time_slice)
+ // {
+ movi a4, _tx_timer_time_slice /* a4 = &_tx_timer_time_slice */
+ l32i a5, a4, 0 /* a5 = _tx_timer_time_slice */
+ beqz a5, .L_tx_timer_no_time_slice
+
+ /* Decrement the time_slice. */
+ // _tx_timer_time_slice--;
+ addi a5, a5, -1
+ s32i a5, a4, 0
+
+ /* Check for expiration. */
+ // if (_tx_timer_time_slice == 0)
+ bnez a5, .L_tx_timer_no_time_slice
+
+ /* Set the time-slice expired flag. */
+ // _tx_timer_expired_time_slice = TX_TRUE;
+ movi a4, _tx_timer_expired_time_slice
+ movi a5, TX_TRUE
+ s32i a5, a4, 0
+
+ // }
+
+.L_tx_timer_no_time_slice:
+
+ /* Test for timer expiration. */
+ // if (*_tx_timer_current_ptr)
+ // {
+ movi a4, _tx_timer_current_ptr /* a4 = &_tx_timer_current_ptr */
+ l32i a5, a4, 0 /* a5 = _tx_timer_current_ptr */
+ l32i a6, a5, 0 /* a6 = *_tx_timer_current_ptr */
+ beqz a6, .L_tx_timer_no_timer
+
+ /* Set expiration flag. */
+ // _tx_timer_expired = TX_TRUE;
+ movi a6, _tx_timer_expired
+ movi a7, TX_TRUE
+ s32i a7, a6, 0
+ j .L_tx_timer_done
+
+ // }
+ // else
+ // {
+
+.L_tx_timer_no_timer:
+
+ /* No timer expired, increment the timer pointer. */
+ // _tx_timer_current_ptr++;
+
+ /* Check for wrap-around. */
+ // if (_tx_timer_current_ptr == _tx_timer_list_end)
+ movi a6, _tx_timer_list_end
+ l32i a6, a6, 0 /* a6 = _tx_timer_list_end */
+ addi a5, a5, 4 /* a5 = ++_tx_timer_current_ptr */
+ bne a5, a6, .L_tx_timer_skip_wrap
+
+ /* Wrap to beginning of list. */
+ // _tx_timer_current_ptr = _tx_timer_list_start;
+ movi a6, _tx_timer_list_start
+ l32i a5, a6, 0 /* a5 = _tx_timer_list_start */
+
+.L_tx_timer_skip_wrap:
+
+ s32i a5, a4, 0 /* _tx_timer_current_ptr = a5 */
+ // }
+
+.L_tx_timer_done:
+
+ /* See if anything has expired. */
+ // if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+ // {
+
+ #ifdef __XTENSA_CALL0_ABI__
+ /* Preserve a2 and a3 across calls. */
+ s32i a2, sp, __tx_timer_interrupt_a2
+ s32i a3, sp, __tx_timer_interrupt_a3
+ #endif
+
+ /* Did a timer expire? */
+ // if (_tx_timer_expired)
+ // {
+ movi a4, _tx_timer_expired
+ l32i a5, a4, 0
+ beqz a5, .L_tx_timer_dont_activate
+
+ /* Call the timer expiration processing. */
+ // _tx_timer_expiration_process();
+ #ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_timer_expiration_process
+ #else
+ call8 _tx_timer_expiration_process
+ #endif
+
+ // }
+
+.L_tx_timer_dont_activate:
+
+ /* Did time slice expire? */
+ // if (_tx_timer_expired_time_slice)
+ // {
+ movi a4, _tx_timer_expired_time_slice
+ l32i a5, a4, 0
+ beqz a5, .L_tx_timer_not_ts_expiration
+
+ /* Time slice interrupted thread. */
+ // _tx_thread_time_slice();
+ #ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_thread_time_slice
+ #else
+ call8 _tx_thread_time_slice
+ #endif
+
+ // }
+
+.L_tx_timer_not_ts_expiration:
+
+ #ifdef __XTENSA_CALL0_ABI__
+ /* Restore a2 and a3. */
+ l32i a2, sp, __tx_timer_interrupt_a2
+ l32i a3, sp, __tx_timer_interrupt_a3
+ #endif
+
+ // }
+
+.Ln_tx_timer_nothing_expired:
+
+ /* Check if we need to process more ticks to catch up. */
+ esync /* ensure comparator update complete */
+ rsr a4, CCOUNT /* a4 = cycle count */
+ sub a4, a4, a3 /* diff = ccount - old comparator */
+ blt a2, a4, .L_tx_timer_catchup /* repeat while diff > divisor */
+
+ RET(16)
+
+// }
+
+#endif /* TX_NO_TIMER */
+
diff --git a/ports/xtensa/xcc/src/tx_xtensa_stack_error_handler.c b/ports/xtensa/xcc/src/tx_xtensa_stack_error_handler.c
new file mode 100644
index 00000000..2d14dd7a
--- /dev/null
+++ b/ports/xtensa/xcc/src/tx_xtensa_stack_error_handler.c
@@ -0,0 +1,123 @@
+/**************************************************************************/
+/* */
+/* 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. */
+/* */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** Support for Xtensa applications */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+
+#include "tx_user.h"
+
+#ifdef TX_ENABLE_STACK_CHECKING
+
+/* Include necessary system files. */
+
+#include "tx_api.h"
+
+#include "xtensa_rtos.h"
+#ifdef XT_BOARD
+#include
+#endif
+#ifdef XT_SIMULATOR
+#include
+#endif
+
+#include
+#include
+#include
+
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Callback to notify of a stack overflow when registered with */
+/* tx_stack_error_notify and stack checking is enabled (ThreadX */
+/* is compiled with TX_ENABLE_STACK_CHECKING defined). */
+/* */
+/* The handler notifies the user in any/all of the following ways: */
+/* - A message via the simulator (extremely reliable, simulator only). */
+/* - A message on the board's display (emulation board only). */
+/* - A message to stdout (uses low-level write to avoid printf which */
+/* is large and would trash state the user might want to examine). */
+/* The most reliable methods are done first. Several might work. */
+/* */
+/* After notifying the user as best it can, the handler stops the */
+/* application in the most reliable of the following ways: */
+/* - Passes control to the debugger (if attached). */
+/* - Terminates the simulation (simulator only). */
+/* - Panics. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+VOID _tx_xtensa_stack_error_handler(TX_THREAD * thread)
+{
+ #ifdef XT_SIMULATOR
+ register int32_t sc __asm__ ("a2") = SYS_log_msg;
+ register char * msg __asm__ ("a3")
+ = "**** Stack overflow in thread 0x%08x.\n";
+ register TX_THREAD * thd __asm__ ("a4") = thread;
+ __asm__ volatile ("simcall" :: "a" (sc), "a" (msg), "a" (thd) );
+ #endif
+
+ #ifdef XT_BOARD
+ xtbsp_display_string("StkOflow");
+ #endif
+
+ write(1, "**** Stack overflow in thread \"", 31);
+ write(1, thread->tx_thread_name, strlen(thread->tx_thread_name));
+ write(1, "\"\n", 2);
+
+ #ifdef XT_SIMULATOR
+ sc = SYS_gdb_abort;
+ __asm__ volatile ("simcall"); /* control to debugger or exit */
+ #else
+ __asm__ volatile ("break 1, 15"); /* control to debugger or panic */
+ #endif
+}
+
+#endif /* TX_ENABLE_STACK_CHECKING */
+
diff --git a/ports/xtensa/xcc/src/xtensa_context.S b/ports/xtensa/xcc/src/xtensa_context.S
new file mode 100644
index 00000000..af3138aa
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_context.S
@@ -0,0 +1,433 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* XTENSA CONTEXT SAVE AND RESTORE ROUTINES */
+/* */
+/* Low-level functions for handling generic context save and restore of */
+/* registers not specifically addressed by the interrupt vectors and */
+/* handlers. Those registers (not handled by these functions) are PC, PS, */
+/* A0, A1 (SP). Except for the calls to RTOS functions, this code is */
+/* generic to Xtensa. */
+/* */
+/* Note that in Call0 ABI, interrupt handlers are expected to preserve */
+/* the callee-save regs (A12-A15), which is always the case if the */
+/* handlers are coded in C. However A12, A13 are made available as */
+/* scratch registers for interrupt dispatch code, so are presumed saved */
+/* anyway, and are always restored even in Call0 ABI. Only A14, A15 are */
+/* truly handled as callee-save regs. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+
+#ifdef XT_USE_OVLY
+#include
+#endif
+
+ .text
+
+#if XCHAL_HAVE_XEA2
+
+/***************************************************************************
+
+ _xt_context_save
+
+ !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
+
+Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in the
+interrupt stack frame defined in xtensa_rtos.h.
+Its counterpart is _xt_context_restore (which also restores A12, A13).
+
+Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame.
+This function preserves A12 & A13 in order to provide the caller with 2 scratch
+regs that need not be saved over the call to this function. The choice of which
+2 regs to provide is governed by xthal_window_spill_nw and xthal_save_extra_nw,
+to avoid moving data more than necessary. Caller can assign regs accordingly.
+
+Entry Conditions:
+ A0 = Return address in caller.
+ A1 = Stack pointer of interrupted thread or handler ("interruptee").
+ Original A12, A13 have already been saved in the interrupt stack frame.
+ Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the
+ point of interruption.
+ If windowed ABI, PS.EXCM = 1 (exceptions disabled).
+
+Exit conditions:
+ A0 = Return address in caller.
+ A1 = Stack pointer of interrupted thread or handler ("interruptee").
+ A12, A13 as at entry (preserved).
+ If windowed ABI, PS.EXCM = 1 (exceptions disabled).
+
+***************************************************************************/
+
+ .global _xt_context_save
+ .type _xt_context_save,@function
+ .align 4
+_xt_context_save:
+
+ s32i a2, sp, XT_STK_A2
+ s32i a3, sp, XT_STK_A3
+ s32i a4, sp, XT_STK_A4
+ s32i a5, sp, XT_STK_A5
+ s32i a6, sp, XT_STK_A6
+ s32i a7, sp, XT_STK_A7
+ s32i a8, sp, XT_STK_A8
+ s32i a9, sp, XT_STK_A9
+ s32i a10, sp, XT_STK_A10
+ s32i a11, sp, XT_STK_A11
+
+ /*
+ Call0 ABI callee-saved regs a12-15 do not need to be saved here.
+ a12-13 are the caller's responsibility so it can use them as scratch.
+ So only need to save a14-a15 here for Windowed ABI (not Call0).
+ */
+ #ifndef __XTENSA_CALL0_ABI__
+ s32i a14, sp, XT_STK_A14
+ s32i a15, sp, XT_STK_A15
+ #endif
+
+ rsr a3, SAR
+ s32i a3, sp, XT_STK_SAR
+
+ #if XCHAL_HAVE_LOOPS
+ rsr a3, LBEG
+ s32i a3, sp, XT_STK_LBEG
+ rsr a3, LEND
+ s32i a3, sp, XT_STK_LEND
+ rsr a3, LCOUNT
+ s32i a3, sp, XT_STK_LCOUNT
+ #endif
+
+ #if XCHAL_HAVE_EXCLUSIVE
+ /* Save and clear state of ATOMCTL */
+ movi a3, 0
+ getex a3
+ s32i a3, sp, XT_STK_ATOMCTL
+ #endif
+
+ #if XT_USE_SWPRI
+ /* Save virtual priority mask */
+ movi a3, _xt_vpri_mask
+ l32i a3, a3, 0
+ s32i a3, sp, XT_STK_VPRI
+ #endif
+
+ #if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
+ mov a9, a0 /* preserve ret addr */
+ #endif
+
+ #ifndef __XTENSA_CALL0_ABI__
+ /*
+ To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15.
+ Need to save a9,12,13 temporarily (in frame temps) and recover originals.
+ Interrupts need to be disabled below XCHAL_EXCM_LEVEL and window overflow
+ and underflow exceptions disabled (assured by PS.EXCM == 1).
+ */
+ s32i a12, sp, XT_STK_TMP0 /* temp. save stuff in stack frame */
+ s32i a13, sp, XT_STK_TMP1
+ s32i a9, sp, XT_STK_TMP2
+
+ /*
+ Save the overlay state if we are supporting overlays. Since we just saved
+ three registers, we can conveniently use them here. Note that as of now,
+ overlays only work for windowed calling ABI.
+ */
+ #ifdef XT_USE_OVLY
+ l32i a9, sp, XT_STK_PC /* recover saved PC */
+ _xt_overlay_get_state a9, a12, a13
+ s32i a9, sp, XT_STK_OVLY /* save overlay state */
+ #endif
+
+ l32i a12, sp, XT_STK_A12 /* recover original a9,12,13 */
+ l32i a13, sp, XT_STK_A13
+ l32i a9, sp, XT_STK_A9
+ addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */
+ call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */
+ addi sp, sp, -XT_STK_FRMSZ
+ l32i a12, sp, XT_STK_TMP0 /* recover stuff from stack frame */
+ l32i a13, sp, XT_STK_TMP1
+ l32i a9, sp, XT_STK_TMP2
+ #endif
+
+ #if XCHAL_EXTRA_SA_SIZE > 0
+ /*
+ NOTE: Normally the xthal_save_extra_nw macro only affects address
+ registers a2-a5. It is theoretically possible for Xtensa processor
+ designers to write TIE that causes more address registers to be
+ affected, but it is generally unlikely. If that ever happens,
+ more registers need to be saved/restored around this macro invocation.
+ Here we assume a9,12,13 are preserved.
+ Future Xtensa tools releases might limit the regs that can be affected.
+ */
+ addi a2, sp, XT_STK_EXTRA /* where to save it */
+ # if XCHAL_EXTRA_SA_ALIGN > 16
+ movi a3, -XCHAL_EXTRA_SA_ALIGN
+ and a2, a2, a3 /* align dynamically >16 bytes */
+ # endif
+ call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */
+ #endif
+
+ #if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
+ mov a0, a9 /* retrieve ret addr */
+ #endif
+
+ ret
+
+/*******************************************************************************
+
+_xt_context_restore
+
+ !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
+
+Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0
+ABI, A14, A15 which are preserved by all interrupt handlers) from an interrupt
+stack frame defined in xtensa_rtos.h .
+Its counterpart is _xt_context_save (whose caller saved A12, A13).
+
+Caller is responsible to restore PC, PS, A0, A1 (SP).
+
+Entry Conditions:
+ A0 = Return address in caller.
+ A1 = Stack pointer of interrupted thread or handler ("interruptee").
+
+Exit conditions:
+ A0 = Return address in caller.
+ A1 = Stack pointer of interrupted thread or handler ("interruptee").
+ Other processor state except PC, PS, A0, A1 (SP), is as at the point
+ of interruption.
+
+*******************************************************************************/
+
+ .global _xt_context_restore
+ .type _xt_context_restore,@function
+ .align 4
+_xt_context_restore:
+
+ #if XCHAL_EXTRA_SA_SIZE > 0
+ /*
+ NOTE: Normally the xthal_restore_extra_nw macro only affects address
+ registers a2-a5. It is theoretically possible for Xtensa processor
+ designers to write TIE that causes more address registers to be
+ affected, but it is generally unlikely. If that ever happens,
+ more registers need to be saved/restored around this macro invocation.
+ Here we only assume a13 is preserved.
+ Future Xtensa tools releases might limit the regs that can be affected.
+ */
+ mov a13, a0 /* preserve ret addr */
+ addi a2, sp, XT_STK_EXTRA /* where to find it */
+ # if XCHAL_EXTRA_SA_ALIGN > 16
+ movi a3, -XCHAL_EXTRA_SA_ALIGN
+ and a2, a2, a3 /* align dynamically >16 bytes */
+ # endif
+ call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */
+ mov a0, a13 /* retrieve ret addr */
+ #endif
+
+ #if XCHAL_HAVE_LOOPS
+ l32i a2, sp, XT_STK_LBEG
+ l32i a3, sp, XT_STK_LEND
+ wsr a2, LBEG
+ l32i a2, sp, XT_STK_LCOUNT
+ wsr a3, LEND
+ wsr a2, LCOUNT
+ #endif
+
+ #if XCHAL_HAVE_EXCLUSIVE
+ /* Restore state of ATOMCTL */
+ l32i a2, sp, XT_STK_ATOMCTL
+ getex a2
+ #endif
+
+ #ifdef XT_USE_OVLY
+ /*
+ If we are using overlays, this is a good spot to check if we need
+ to restore an overlay for the incoming task. Here we have a bunch
+ of registers to spare. Note that this step is going to use a few
+ bytes of storage below SP (SP-20 to SP-32) if an overlay is going
+ to be restored.
+ */
+ l32i a2, sp, XT_STK_PC /* retrieve PC */
+ l32i a3, sp, XT_STK_PS /* retrieve PS */
+ l32i a4, sp, XT_STK_OVLY /* retrieve overlay state */
+ l32i a5, sp, XT_STK_A1 /* retrieve stack ptr */
+ _xt_overlay_check_map a2, a3, a4, a5, a6
+ s32i a2, sp, XT_STK_PC /* save updated PC */
+ s32i a3, sp, XT_STK_PS /* save updated PS */
+ #endif
+
+ #ifdef XT_USE_SWPRI
+ /* Restore virtual interrupt priority and interrupt enable */
+ movi a3, _xt_intdata
+ l32i a4, a3, 0 /* a4 = _xt_intenable */
+ l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */
+ and a4, a4, a5
+ wsr a4, INTENABLE /* update INTENABLE */
+ s32i a5, a3, 4 /* restore _xt_vpri_mask */
+ #endif
+
+ l32i a3, sp, XT_STK_SAR
+ l32i a2, sp, XT_STK_A2
+ wsr a3, SAR
+ l32i a3, sp, XT_STK_A3
+ l32i a4, sp, XT_STK_A4
+ l32i a5, sp, XT_STK_A5
+ l32i a6, sp, XT_STK_A6
+ l32i a7, sp, XT_STK_A7
+ l32i a8, sp, XT_STK_A8
+ l32i a9, sp, XT_STK_A9
+ l32i a10, sp, XT_STK_A10
+ l32i a11, sp, XT_STK_A11
+
+ /*
+ Call0 ABI callee-saved regs a12-15 do not need to be restored here.
+ However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(),
+ so need to be restored anyway, despite being callee-saved in Call0.
+ */
+ l32i a12, sp, XT_STK_A12
+ l32i a13, sp, XT_STK_A13
+ #ifndef __XTENSA_CALL0_ABI__
+ l32i a14, sp, XT_STK_A14
+ l32i a15, sp, XT_STK_A15
+ #endif
+
+ ret
+
+#endif /* XCHAL_HAVE_XEA3 */
+
+
+/*******************************************************************************
+
+_xt_coproc_init
+
+Initializes global co-processor management data, setting all co-processors
+to "unowned". Leaves CPENABLE as it found it (does NOT clear it).
+
+Called during initialization of the RTOS, before any threads run.
+
+This may be called from normal Xtensa single-threaded application code which
+might use co-processors. The Xtensa run-time initialization enables all
+co-processors. They must remain enabled here, else a co-processor exception
+might occur outside of a thread, which the exception handler doesn't expect.
+
+Entry Conditions:
+ Xtensa single-threaded run-time environment is in effect.
+ No thread is yet running.
+
+Exit conditions:
+ None.
+
+Obeys ABI conventions per prototype:
+ void _xt_coproc_init(void)
+
+*******************************************************************************/
+
+#if XCHAL_CP_NUM > 0
+
+ .global _xt_coproc_init
+ .type _xt_coproc_init,@function
+ .align 4
+_xt_coproc_init:
+ ENTRY0
+
+ /* Initialize thread co-processor ownerships to 0 (unowned). */
+ movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
+ addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */
+ movi a4, 0 /* a4 = 0 (unowned) */
+1: s32i a4, a2, 0
+ addi a2, a2, 4
+ bltu a2, a3, 1b
+
+ RET0
+
+#endif
+
+
+/*******************************************************************************
+
+_xt_coproc_release
+
+Releases any and all co-processors owned by a given thread. The thread is
+identified by it's co-processor state save area defined in xtensa_context.h .
+
+Must be called before a thread's co-proc save area is deleted to avoid
+memory corruption when the exception handler tries to save the state.
+May be called when a thread terminates or completes but does not delete
+the co-proc save area, to avoid the exception handler having to save the
+thread's co-proc state before another thread can use it (optimization).
+
+Entry Conditions:
+ A2 = Pointer to base of co-processor state save area.
+
+Exit conditions:
+ None.
+
+Obeys ABI conventions per prototype:
+ void _xt_coproc_release(void * coproc_sa_base)
+
+*******************************************************************************/
+
+#if XCHAL_CP_NUM > 0
+
+ .global _xt_coproc_release
+ .type _xt_coproc_release,@function
+ .align 4
+_xt_coproc_release:
+ ENTRY0 /* a2 = base of save area */
+
+ movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
+ addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */
+ movi a5, 0 /* a5 = 0 (unowned) */
+
+#if XCHAL_HAVE_XEA3
+ movi a6, PS_DI
+ xps a6, a6 /* lock interrupts */
+#else
+ rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */
+#endif
+
+1: l32i a7, a3, 0 /* a7 = owner at a3 */
+ bne a2, a7, 2f /* if (coproc_sa_base == owner) */
+ s32i a5, a3, 0 /* owner = unowned */
+2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */
+ bltu a3, a4, 1b /* repeat until end of array */
+
+3:
+ wsr a6, PS /* restore interrupts */
+ rsync
+
+ RET0
+
+#endif
+
diff --git a/ports/xtensa/xcc/src/xtensa_coproc_handler.S b/ports/xtensa/xcc/src/xtensa_coproc_handler.S
new file mode 100644
index 00000000..ee55e471
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_coproc_handler.S
@@ -0,0 +1,578 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa coprocessor handling routines. This code is only active if */
+/* one or more coprocessors are present. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include
+#include
+
+#include "xtensa_context.h"
+#include "xtensa_rtos.h"
+
+
+#if XCHAL_CP_NUM > 0
+
+//-----------------------------------------------------------------------------
+// Coprocessor related state and precomputed values.
+//-----------------------------------------------------------------------------
+
+// Table of coprocessor owners, identified by thread's CP save area pointer.
+// Zero means coprocessor is not owned.
+
+ .data
+ .global _xt_coproc_owner_sa
+ .align 16,,XCHAL_CP_MAX << 2 // minimize crossing cache boundaries
+_xt_coproc_owner_sa:
+ .rept XCHAL_CP_MAX
+ .word 0
+ .endr
+
+// Bitmask table for CP n's enable bit, indexed by coprocessor number.
+
+ .section .rodata, "a"
+ .global _xt_coproc_mask
+ .align 16,,8 // try to keep it all in one cache line
+ .set i, 0
+_xt_coproc_mask:
+ .rept XCHAL_CP_MAX
+ .long (i<<16) | (1<tx_thread_cp_state) : 0 )
+
+ movi a15, _tx_thread_system_state // check if interrupt state
+ l32i a15, a15, 0
+ bnez a15, 1f
+ movi a15, _tx_thread_current_ptr // check if thread running
+ l32i a15, a15, 0
+ beqz a15, 2f
+
+ // Return base address of current thread's co-prcoessor save area.
+ addi a15, a15, tx_thread_cp_state
+ ret
+1:
+ movi a15, 0 // return error
+2:
+ ret
+
+
+//-----------------------------------------------------------------------------
+// _xt_coproc_savecs
+//
+// If there is a current thread and it has a coprocessor state save area, then
+// save all callee-saved state into this area. This function is called from the
+// solicited context switch handler. It calls a system-specific function to get
+// the coprocessor save area base address.
+//
+// Entry conditions:
+// - The thread being switched out is still the current thread.
+// - CPENABLE state reflects which coprocessors are active.
+// - Registers have been saved/spilled already.
+//
+// Exit conditions:
+// - All necessary CP callee-saved state has been saved.
+// - Registers a7-a15 have been trashed.
+//
+// Must be called from assembly code only, using CALL0.
+//-----------------------------------------------------------------------------
+
+ .global _xt_coproc_savecs
+ .type _xt_coproc_savecs,@function
+ .align 4
+_xt_coproc_savecs:
+
+ // At entry, CPENABLE should be showing which CPs are enabled.
+
+ rsr a11, CPENABLE // a11 = which CPs are enabled
+ beqz a11, .Ldone // quick exit if none
+ mov a14, a0 // save return address
+ call0 XT_RTOS_CP_STATE // get address of CP save area
+ mov a0, a14 // restore return address
+ beqz a15, .Ldone // if none then nothing to do
+ l32i a14, a15, XT_CP_ASA // a14 = base of aligned save area
+ beqz a14, .Ldone // no save area, nothing to do
+ s16i a11, a15, XT_CP_CS_ST // save mask of CPs being stored
+ movi a13, _xt_coproc_sa_offset // array of CP save offsets
+ l32i a15, a15, XT_CP_ASA // a15 = base of aligned save area
+
+#if XCHAL_CP0_SA_SIZE
+ bbci.l a11, 0, 2f // CP 0 not enabled
+ l32i a14, a13, 0 // a14 = _xt_coproc_sa_offset[0]
+ add a12, a14, a15 // a12 = save area for CP 0
+ xchal_cp0_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP1_SA_SIZE
+ bbci.l a11, 1, 2f // CP 1 not enabled
+ l32i a14, a13, 4 // a14 = _xt_coproc_sa_offset[1]
+ add a12, a14, a15 // a12 = save area for CP 1
+ xchal_cp1_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP2_SA_SIZE
+ bbci.l a11, 2, 2f
+ l32i a14, a13, 8
+ add a12, a14, a15
+ xchal_cp2_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP3_SA_SIZE
+ bbci.l a11, 3, 2f
+ l32i a14, a13, 12
+ add a12, a14, a15
+ xchal_cp3_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP4_SA_SIZE
+ bbci.l a11, 4, 2f
+ l32i a14, a13, 16
+ add a12, a14, a15
+ xchal_cp4_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP5_SA_SIZE
+ bbci.l a11, 5, 2f
+ l32i a14, a13, 20
+ add a12, a14, a15
+ xchal_cp5_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP6_SA_SIZE
+ bbci.l a11, 6, 2f
+ l32i a14, a13, 24
+ add a12, a14, a15
+ xchal_cp6_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP7_SA_SIZE
+ bbci.l a11, 7, 2f
+ l32i a14, a13, 28
+ add a12, a14, a15
+ xchal_cp7_store a12, a7, a8, a9, a10 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+.Ldone:
+ ret
+
+
+//-----------------------------------------------------------------------------
+// _xt_coproc_restorecs
+//
+// Restore any callee-saved coprocessor state for the incoming thread.
+// This function is called from coprocessor exception handling, when giving
+// ownership to a thread that solicited a context switch earlier. It calls a
+// system-specific function to get the coprocessor save area base address.
+//
+// Entry conditions:
+// - The incoming thread is set as the current thread.
+// - CPENABLE is set up correctly for all required coprocessors.
+// - a2 = mask of coprocessors to be restored.
+//
+// Exit conditions:
+// - All necessary CP callee-saved state has been restored.
+// - CPENABLE - unchanged.
+// - Registers a2, a8-a15 have been trashed.
+//
+// Must be called from assembly code only, using CALL0.
+//-----------------------------------------------------------------------------
+
+ .global _xt_coproc_restorecs
+ .type _xt_coproc_restorecs,@function
+ .align 4
+_xt_coproc_restorecs:
+
+ mov a14, a0 // save return address
+ call0 XT_RTOS_CP_STATE // get address of CP save area
+ mov a0, a14 // restore return address
+ beqz a15, .Ldone2 // if none then nothing to do
+ l32i a14, a15, XT_CP_ASA // a14 = base of aligned save area
+ beqz a14, .Ldone2 // no save area, nothing to do
+ l16ui a13, a15, XT_CP_CS_ST // a13 = which CPs have been saved
+ xor a13, a13, a2 // clear the ones being restored
+ s16i a13, a15, XT_CP_CS_ST // update saved CP mask
+ movi a13, _xt_coproc_sa_offset // array of CP save offsets
+ l32i a15, a15, XT_CP_ASA // a15 = base of aligned save area
+
+#if XCHAL_CP0_SA_SIZE
+ bbci.l a2, 0, 2f // CP 0 not enabled
+ l32i a14, a13, 0 // a14 = _xt_coproc_sa_offset[0]
+ add a12, a14, a15 // a12 = save area for CP 0
+ xchal_cp0_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP1_SA_SIZE
+ bbci.l a2, 1, 2f // CP 1 not enabled
+ l32i a14, a13, 4 // a14 = _xt_coproc_sa_offset[1]
+ add a12, a14, a15 // a12 = save area for CP 1
+ xchal_cp1_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP2_SA_SIZE
+ bbci.l a2, 2, 2f
+ l32i a14, a13, 8
+ add a12, a14, a15
+ xchal_cp2_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP3_SA_SIZE
+ bbci.l a2, 3, 2f
+ l32i a14, a13, 12
+ add a12, a14, a15
+ xchal_cp3_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP4_SA_SIZE
+ bbci.l a2, 4, 2f
+ l32i a14, a13, 16
+ add a12, a14, a15
+ xchal_cp4_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP5_SA_SIZE
+ bbci.l a2, 5, 2f
+ l32i a14, a13, 20
+ add a12, a14, a15
+ xchal_cp5_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP6_SA_SIZE
+ bbci.l a2, 6, 2f
+ l32i a14, a13, 24
+ add a12, a14, a15
+ xchal_cp6_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+#if XCHAL_CP7_SA_SIZE
+ bbci.l a2, 7, 2f
+ l32i a14, a13, 28
+ add a12, a14, a15
+ xchal_cp7_load a12, a8, a9, a10, a11 continue=0 ofs=-1 select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
+2:
+#endif
+
+.Ldone2:
+ ret
+
+
+#if XCHAL_HAVE_XEA3
+
+//-----------------------------------------------------------------------------
+// For XEA3, coprocessor exceptions come here. This is a wrapper function that
+// calls _xt_coproc_handler() to do the actual work. Since the handler can be
+// interrupted make sure that no context switch occurs.
+//-----------------------------------------------------------------------------
+
+ .text
+ .global _xt_coproc_exc
+ .type _xt_coproc_exc,@function
+ .align 4
+
+_xt_coproc_exc:
+#ifdef __XTENSA_CALL0_ABI__
+ addi a1, a1, -16 // reserve 16 bytes on stack
+ s32i a0, a1, 0 // save return address
+ s32i a2, a1, 4 // save a2
+ s32i a15, a1, 8 // must save a15 (see dispatch)
+ l32i a2, a1, 4
+ l32i a3, a2, XT_STK_EXCCAUSE // a3 <- exccause
+ extui a2, a3, 8, 4 // a2 <- CP index
+ call0 _xt_coproc_handler
+ l32i a0, a1, 0 // restore return address
+ l32i a15, a1, 8 // restore a15
+ addi a1, a1, 16
+ ret
+#else
+ entry a1, 48 // reserve 16 bytes on stack
+ s32i a0, a1, 0 // save return address
+ l32i a3, a2, XT_STK_EXCCAUSE // a3 <- exccause
+ extui a2, a3, 8, 4 // a2 <- CP index
+ call0 _xt_coproc_handler
+ l32i a0, a1, 0 // restore return address
+ retw
+#endif
+
+#endif // XCHAL_HAVE_XEA3
+
+
+#if XCHAL_HAVE_XEA2
+
+//-----------------------------------------------------------------------------
+// XEA2 coprocessor exception dispatcher. Save enough state to be able to call
+// the coprocessor handler, then restore and return.
+//-----------------------------------------------------------------------------
+
+ .text
+ .global _xt_coproc_exc
+ .type _xt_coproc_exc,@function
+ .align 4
+
+_xt_coproc_exc:
+
+ mov a0, sp // Allocate stack frame
+ addi sp, sp, -XT_STK_FRMSZ
+ s32i a0, sp, XT_STK_A1 // save SP
+#if XCHAL_HAVE_WINDOWED
+ s32e a0, sp, -12 // for debug backtrace
+#endif
+ rsr a0, PS
+ s32i a0, sp, XT_STK_PS // save PS
+ rsr a0, EPC_1
+ s32i a0, sp, XT_STK_PC // save PC
+ rsr a0, EXCSAVE_1
+ s32i a0, sp, XT_STK_A0 // retrieve and save a0
+#if XCHAL_HAVE_WINDOWED
+ s32e a0, sp, -16 // for debug backtrace
+#endif
+ s32i a2, sp, XT_STK_A2
+ s32i a3, sp, XT_STK_A3
+ s32i a4, sp, XT_STK_A4
+ s32i a5, sp, XT_STK_A5
+ s32i a6, sp, XT_STK_A6
+ s32i a7, sp, XT_STK_A7
+ s32i a8, sp, XT_STK_A8
+ s32i a9, sp, XT_STK_A9
+ s32i a10, sp, XT_STK_A10
+ s32i a11, sp, XT_STK_A11
+ s32i a12, sp, XT_STK_A12
+ s32i a13, sp, XT_STK_A13
+ s32i a14, sp, XT_STK_A14
+ s32i a15, sp, XT_STK_A15
+
+ rsr a3, EXCCAUSE // a3 <- exccause
+ addi a2, a3, -EXCCAUSE_CP0_DISABLED // a2 <- CP index
+ call0 _xt_coproc_handler
+
+ mov a0, a2 // save return value
+ l32i a2, sp, XT_STK_A2
+ l32i a3, sp, XT_STK_A3
+ l32i a4, sp, XT_STK_A4
+ l32i a5, sp, XT_STK_A5
+ l32i a6, sp, XT_STK_A6
+ l32i a7, sp, XT_STK_A7
+ l32i a8, sp, XT_STK_A8
+ l32i a9, sp, XT_STK_A9
+ l32i a10, sp, XT_STK_A10
+ l32i a11, sp, XT_STK_A11
+ l32i a12, sp, XT_STK_A12
+ l32i a13, sp, XT_STK_A13
+ l32i a14, sp, XT_STK_A14
+ l32i a15, sp, XT_STK_A15
+ bnez a0, .Lfail // abort if failure
+ l32i a0, sp, XT_STK_PC
+ wsr a0, EPC_1 // restore PC
+ l32i a0, sp, XT_STK_PS
+ wsr a0, PS // restore PS
+ l32i a0, sp, XT_STK_A0
+ addi a1, a1, XT_STK_FRMSZ // deallocate stack frame
+ rfe
+
+.Lfail:
+ call0 _xt_panic
+
+#endif // XCHAL_HAVE_XEA2
+
+#endif // XCHAL_CP_NUM > 0
+
diff --git a/ports/xtensa/xcc/src/xtensa_init.c b/ports/xtensa/xcc/src/xtensa_init.c
new file mode 100644
index 00000000..0359028c
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_init.c
@@ -0,0 +1,67 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa initialization routines. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#ifdef XT_BOARD
+#include
+#endif
+
+#include "xtensa_rtos.h"
+
+
+#ifdef XT_RTOS_TIMER_INT
+#ifndef XT_CLOCK_FREQ
+
+uint32_t _xt_tick_divisor = 0; /* cached number of cycles per tick */
+
+/*
+Compute and initialize at run-time the tick divisor (the number of
+processor clock cycles in an RTOS tick, used to set the tick timer).
+Called when the processor clock frequency is not known at compile-time.
+*/
+void _xt_tick_divisor_init(void)
+{
+ #ifdef XT_BOARD
+ _xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC;
+ #else
+ #error "No way to obtain processor clock frequency"
+ #endif /* XT_BOARD */
+}
+
+#endif /* XT_CLOCK_FREQ */
+#endif /* XT_RTOS_TIMER_INT */
+
diff --git a/ports/xtensa/xcc/src/xtensa_intr.c b/ports/xtensa/xcc/src/xtensa_intr.c
new file mode 100644
index 00000000..c5f320cb
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_intr.c
@@ -0,0 +1,213 @@
+/*******************************************************************************
+Copyright (c) 2006-2019 Cadence Design Systems Inc.
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+******************************************************************************/
+
+/******************************************************************************
+ Xtensa-specific interrupt and exception functions for RTOS ports.
+ Also see xtensa_intr_asm.S.
+******************************************************************************/
+
+#include
+
+#include
+#include
+
+#include "xtensa_api.h"
+
+
+#if XCHAL_HAVE_EXCEPTIONS
+
+/* Handler table is in xtensa_intr_asm.S */
+
+extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
+
+
+/*
+ Default handler for unhandled exceptions.
+*/
+void xt_unhandled_exception(XtExcFrame *frame)
+{
+ (void) frame; /* Keep compiler happy */
+ exit(-1);
+}
+
+
+/*
+ This function registers a handler for the specified exception.
+ The function returns the address of the previous handler.
+ On error, it returns 0.
+*/
+xt_exc_handler xt_set_exception_handler(uint32_t n, xt_exc_handler f)
+{
+ xt_exc_handler old;
+
+ if (n >= XCHAL_EXCCAUSE_NUM) {
+ return 0; /* invalid exception number */
+ }
+
+ old = _xt_exception_table[n];
+
+ if (f != NULL) {
+ _xt_exception_table[n] = f;
+ }
+ else {
+ _xt_exception_table[n] = &xt_unhandled_exception;
+ }
+
+ return old;
+}
+
+#endif
+
+#if XCHAL_HAVE_INTERRUPTS
+
+#if XCHAL_HAVE_XEA2
+/* Defined in xtensa_intr_asm.S */
+extern uint32_t _xt_intenable;
+extern uint32_t _xt_vpri_mask;
+#endif
+
+/* Handler table is in xtensa_intr_asm.S */
+
+typedef struct xt_handler_table_entry {
+ void * handler;
+ void * arg;
+} xt_handler_table_entry;
+
+#if (XT_USE_INT_WRAPPER || XCHAL_HAVE_XEA3)
+extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS + 1];
+#else
+extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS];
+#endif
+
+
+/*
+ Default handler for unhandled interrupts.
+*/
+void xt_unhandled_interrupt(void * arg)
+{
+ (void) arg; /* Keep compiler happy */
+ exit(-1);
+}
+
+
+/*
+ This function registers a handler for the specified interrupt. The "arg"
+ parameter specifies the argument to be passed to the handler when it is
+ invoked. The function returns the address of the previous handler.
+ On error, it returns 0.
+*/
+xt_handler xt_set_interrupt_handler(uint32_t n, xt_handler f, void * arg)
+{
+ xt_handler_table_entry * entry;
+ xt_handler old;
+
+ if (n >= XCHAL_NUM_INTERRUPTS) {
+ return 0; /* invalid interrupt number */
+ }
+
+#if XCHAL_HAVE_XEA2
+ if (Xthal_intlevel[n] > XCHAL_EXCM_LEVEL) {
+ return 0; /* priority level too high to safely handle in C */
+ }
+#endif
+
+#if (XT_USE_INT_WRAPPER || XCHAL_HAVE_XEA3)
+ entry = _xt_interrupt_table + n + 1;
+#else
+ entry = _xt_interrupt_table + n;
+#endif
+ old = entry->handler;
+
+ if (f != NULL) {
+ entry->handler = f;
+ entry->arg = arg;
+ }
+ else {
+ entry->handler = &xt_unhandled_interrupt;
+ entry->arg = (void*)n;
+ }
+
+ return old;
+}
+
+
+/*
+ This function enables the interrupt whose number is specified as
+ the argument.
+*/
+void xt_interrupt_enable(uint32_t intnum)
+{
+#if XCHAL_HAVE_XEA2
+ uint32_t ps = XT_RSIL(15);
+
+ // New INTENABLE = (_xt_intenable | mask) & _xt_vpri_mask.
+ _xt_intenable |= (1 << intnum);
+ XT_WSR_INTENABLE(_xt_intenable & _xt_vpri_mask);
+ XT_WSR_PS(ps);
+ XT_RSYNC();
+#else
+ xthal_interrupt_enable(intnum);
+#endif
+}
+
+
+/*
+ This function disables the interrupt whose number is specified as
+ the argument.
+*/
+void xt_interrupt_disable(uint32_t intnum)
+{
+#if XCHAL_HAVE_XEA2
+ uint32_t ps = XT_RSIL(15);
+
+ // New INTENABLE = (_xt_intenable & ~mask) & _xt_vpri_mask.
+ _xt_intenable &= ~(1 << intnum);
+ XT_WSR_INTENABLE(_xt_intenable & _xt_vpri_mask);
+ XT_WSR_PS(ps);
+ XT_RSYNC();
+#else
+ xthal_interrupt_disable(intnum);
+#endif
+}
+
+
+/*
+ This function triggers the specified interrupt.
+*/
+void xt_interrupt_trigger(uint32_t intnum)
+{
+ xthal_interrupt_trigger(intnum);
+}
+
+
+/*
+ This function clears the specified interrupt.
+*/
+void xt_interrupt_clear(uint32_t intnum)
+{
+ xthal_interrupt_clear(intnum);
+}
+
+
+#endif /* XCHAL_HAVE_INTERRUPTS */
+
diff --git a/ports/xtensa/xcc/src/xtensa_intr_asm.S b/ports/xtensa/xcc/src/xtensa_intr_asm.S
new file mode 100644
index 00000000..78fd8a70
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_intr_asm.S
@@ -0,0 +1,156 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa interrupt handling data and assembly routines. */
+/* Also see xtensa_intr.c. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include
+#include
+
+#include "tx_port.h"
+#include "xtensa_context.h"
+
+#if XCHAL_HAVE_INTERRUPTS
+
+/*
+-------------------------------------------------------------------------------
+ INTENABLE virtualization information.
+-------------------------------------------------------------------------------
+*/
+
+#if XCHAL_HAVE_XEA2
+
+ .data
+ .global _xt_intdata
+ .align 8
+_xt_intdata:
+ .global _xt_intenable
+ .type _xt_intenable,@object
+ .size _xt_intenable,4
+ .global _xt_vpri_mask
+ .type _xt_vpri_mask,@object
+ .size _xt_vpri_mask,4
+
+_xt_intenable: .word 0 /* Virtual INTENABLE */
+_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
+
+#endif
+
+/*
+-------------------------------------------------------------------------------
+ System interrupt stack.
+-------------------------------------------------------------------------------
+*/
+
+#if (XCHAL_HAVE_XEA2 || XCHAL_HAVE_ISB)
+ .data
+#else
+ .section .intr.top, "aw"
+#endif
+
+ .global _xt_interrupt_stack
+ .global _xt_interrupt_stack_top
+ .align 16
+
+_xt_interrupt_stack:
+ .space TX_SYSTEM_STACK_SIZE
+_xt_interrupt_stack_top:
+
+
+/*
+-------------------------------------------------------------------------------
+ Table of C-callable interrupt handlers for each interrupt. For XEA2 configs,
+ not all slots can be filled, because interrupts at level > EXCM_LEVEL will
+ not be dispatched to a C handler by default.
+-------------------------------------------------------------------------------
+*/
+
+#if (XCHAL_HAVE_XEA2 || XCHAL_HAVE_ISB)
+ .data
+#else
+ .section .intr.data, "aw"
+#endif
+
+ .global _xt_interrupt_table
+ .align 16
+
+_xt_interrupt_table:
+
+/*
+-------------------------------------------------------------------------------
+ If using the interrupt wrapper, make the first entry in the interrupt table
+ point to the wrapper (XEA3) or leave it empty (XEA2).
+-------------------------------------------------------------------------------
+*/
+#if XCHAL_HAVE_XEA3
+ .word xt_interrupt_wrapper
+ .word 0
+#elif XT_USE_INT_WRAPPER
+ .word 0
+ .word 0
+#endif
+
+ .set i, 0
+ .rept XCHAL_NUM_INTERRUPTS
+ .word xt_unhandled_interrupt /* handler address */
+ .word i /* handler arg (default: intnum) */
+ .set i, i+1
+ .endr
+
+#endif /* XCHAL_HAVE_INTERRUPTS */
+
+
+#if XCHAL_HAVE_EXCEPTIONS
+
+/*
+-------------------------------------------------------------------------------
+ Table of C-callable exception handlers for each exception. Note that not all
+ slots will be active, because some exceptions (e.g. coprocessor exceptions)
+ are always handled by the OS and cannot be hooked by user handlers.
+-------------------------------------------------------------------------------
+*/
+
+ .data
+ .global _xt_exception_table
+ .align 4
+
+_xt_exception_table:
+ .rept XCHAL_EXCCAUSE_NUM
+ .word xt_unhandled_exception /* handler address */
+ .endr
+
+#endif
+
diff --git a/ports/xtensa/xcc/src/xtensa_intr_wrapper.c b/ports/xtensa/xcc/src/xtensa_intr_wrapper.c
new file mode 100644
index 00000000..ff70f4ea
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_intr_wrapper.c
@@ -0,0 +1,125 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa-specific interrupt handler wrapper. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include
+#include
+
+#include "xtensa_rtos.h"
+#include "xtensa_api.h"
+
+#include "tx_api.h"
+#include "tx_thread.h"
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+#include "tx_execution_profile.h"
+#endif
+
+
+#if (XCHAL_HAVE_XEA3 && XCHAL_HAVE_INTERRUPTS)
+
+/* Table of interrupt hooks. Used for testing ONLY. */
+#ifdef XT_INTEXC_HOOKS
+volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
+#endif
+
+
+/* Handler table is in xtensa_intr_asm.S */
+
+typedef struct xt_handler_table_entry {
+ void * handler;
+ void * arg;
+} xt_handler_table_entry;
+
+extern xt_handler_table_entry _xt_interrupt_table[XCHAL_NUM_INTERRUPTS + 1];
+extern int32_t xt_sw_intnum;
+
+static int32_t xt_wflag;
+
+
+/**************************************************************************/
+/* Wrapper for interrupt handlers. Argument is (intnum << 2). */
+/* Execution comes here from the dispatch code if the wrapper is */
+/* enabled. */
+/**************************************************************************/
+void
+xt_interrupt_wrapper(void * arg)
+{
+ uint32_t intnum = (uint32_t)(arg) >> 2;
+ xt_handler_table_entry * entry;
+ xt_handler handler;
+
+ /* Increment interrupt nest counter. */
+ _tx_thread_system_state++;
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the ISR enter function to indicate an ISR is executing. */
+ _tx_execution_isr_enter();
+#endif
+
+ /* Load handler address and argument from table. Note that the
+ first entry in the table points to this wrapper, so we have
+ to skip ahead one.
+ */
+ entry = _xt_interrupt_table + intnum + 1;
+ handler = (xt_handler) entry->handler;
+
+ (*handler)(entry->arg);
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the ISR exit function to indicate an ISR is complete. */
+ _tx_execution_isr_exit();
+#endif
+
+ /* If a context switch is pending, trigger the SW interrupt
+ to process the switch. Set an internal flag so we don't
+ trigger the sw interrupt again when handling it.
+ */
+ if (xt_wflag != 0) {
+ xt_wflag = 0;
+ }
+ else if (_tx_thread_current_ptr != _tx_thread_execute_ptr) {
+ xt_wflag = 1;
+ xt_interrupt_trigger(xt_sw_intnum);
+ }
+
+ /* Decrement interrupt nest counter. */
+ _tx_thread_system_state--;
+}
+
+#endif /* XCHAL_HAVE_XEA3 && XCHAL_HAVE_INTERRUPTS */
+
diff --git a/ports/xtensa/xcc/src/xtensa_overlay_os_hook.c b/ports/xtensa/xcc/src/xtensa_overlay_os_hook.c
new file mode 100644
index 00000000..8fd92701
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_overlay_os_hook.c
@@ -0,0 +1,109 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa overlay manager OS hooks for ThreadX. XEA2 only. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#ifdef XT_USE_OVLY
+
+#include
+#include "tx_api.h"
+
+
+/* Required to work around a bug in the overlay header. */
+#ifdef XT_DISABLE_OVERLAYS
+#undef xt_overlay_fatal_error
+#define xt_overlay_fatal_error(id)
+#endif
+
+
+/* Mutex object that controls access to the overlay. Currently only one
+ * overlay region is supported so one mutex suffices.
+ */
+static TX_MUTEX xt_overlay_mutex;
+
+
+/**************************************************************************/
+/* This function should be overridden to provide OS specific init such */
+/* as the creation of a mutex lock that can be used for overlay locking. */
+/* Typically this mutex would be set up with priority inheritance. See */
+/* overlay manager documentation for more details. */
+/**************************************************************************/
+void
+xt_overlay_init_os(void)
+{
+ /* Create the mutex for overlay access. Priority inheritance is
+ * required.
+ */
+ UINT status =
+ tx_mutex_create (&xt_overlay_mutex, "xt_overlay_lock", TX_INHERIT);
+
+ if (status != TX_SUCCESS) {
+ xt_overlay_fatal_error (-1);
+ }
+}
+
+
+/**************************************************************************/
+/* This function locks access to shared overlay resources, typically */
+/* by acquiring a mutex. */
+/**************************************************************************/
+void
+xt_overlay_lock(void)
+{
+ UINT status = tx_mutex_get (&xt_overlay_mutex, TX_WAIT_FOREVER);
+
+ if (status != TX_SUCCESS) {
+ xt_overlay_fatal_error (-1);
+ }
+}
+
+
+/**************************************************************************/
+/* This function releases access to shared overlay resources, typically */
+/* by unlocking a mutex. */
+/**************************************************************************/
+void
+xt_overlay_unlock(void)
+{
+ UINT status = tx_mutex_put (&xt_overlay_mutex);
+
+ if (status != TX_SUCCESS) {
+ xt_overlay_fatal_error (-1);
+ }
+}
+
+#endif /* XT_USE_OVLY */
+
diff --git a/ports/xtensa/xcc/src/xtensa_vectors.S b/ports/xtensa/xcc/src/xtensa_vectors.S
new file mode 100644
index 00000000..b115abf5
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_vectors.S
@@ -0,0 +1,1696 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa exception and interrupt dispatch for XEA2. */
+/* */
+/* Interrupt handlers and user exception handlers support interaction */
+/* with the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT */
+/* before and after calling the user's specific interrupt handlers. */
+/* */
+/* Users can install application-specific interrupt handlers for low and */
+/* medium priority interrupts, by calling xt_set_interrupt_handler(). */
+/* These handlers can be written in C and must follow the C calling */
+/* convention. The handler table is indexed by the interrupt number. */
+/* Each handler may be provided with an argument. */
+/* */
+/* Note that the system timer interrupt is handled specially, and is */
+/* dispatched to the RTOS-specific handler. This timer cannot be hooked */
+/* by application code. */
+/* */
+/* Optional hooks are also provided to install a handler per level at */
+/* run-time, made available by compiling this source file with */
+/* '-DXT_INTEXC_HOOKS' (useful for automated testing). */
+/* */
+/* Search for locations marked USER_EDIT for helpful comments on where */
+/* to insert application-specific code and how to write them. */
+/* */
+/* Users can install application-specific exception handlers in the */
+/* same way, by calling xt_set_exception_handler(). One handler slot is */
+/* provided for each exception type. Note that some exceptions are */
+/* handled by the porting layer itself, and cannot be taken over by */
+/* application code. These are the alloca, syscall, and coprocessor */
+/* exceptions. */
+/* */
+/* Exception handlers can be written in C, and must follow C calling */
+/* convention. Each handler is passed a pointer to an exception frame as */
+/* its single argument. The exception frame is created on the stack and */
+/* holds the saved context of the thread that took the exception. If the */
+/* handler returns, the context will be restored and the instruction */
+/* that caused the exception will be retried. If the handler makes any */
+/* changes to the saved state in the exception frame, the changes will */
+/* be applied when restoring the context. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include "xtensa_rtos.h"
+
+
+#if XCHAL_HAVE_XEA2
+
+/* Enable stack backtrace across exception/interrupt - see below */
+#define XT_DEBUG_BACKTRACE 1
+
+
+/*
+--------------------------------------------------------------------------------
+ Defines used to access _xtos_interrupt_table.
+--------------------------------------------------------------------------------
+*/
+#define XIE_HANDLER 0
+#define XIE_ARG 4
+#define XIE_SIZE 8
+
+/*
+--------------------------------------------------------------------------------
+ Macro extract_msb - return the input with only the highest bit set.
+
+ Input : "ain" - Input value, clobbered.
+ Output : "aout" - Output value, has only one bit set, MSB of "ain".
+ The two arguments must be different AR registers.
+--------------------------------------------------------------------------------
+*/
+
+ .macro extract_msb aout ain
+1:
+ addi \aout, \ain, -1 /* aout = ain - 1 */
+ and \ain, \ain, \aout /* ain = ain & aout */
+ bnez \ain, 1b /* repeat until ain == 0 */
+ addi \aout, \aout, 1 /* return aout + 1 */
+ .endm
+
+/*
+--------------------------------------------------------------------------------
+ Macro dispatch_c_isr - dispatch interrupts to user ISRs.
+ This will dispatch to user handlers (if any) that are registered in the
+ XTOS dispatch table (_xtos_interrupt_table). These handlers would have
+ been registered by calling _xtos_set_interrupt_handler(). There is one
+ exception - the timer interrupt used by the OS will not be dispatched
+ to a user handler - this must be handled by the caller of this macro.
+
+ Level triggered and software interrupts are automatically deasserted by
+ this code.
+
+ ASSUMPTIONS:
+ -- PS.INTLEVEL is set to "level" at entry
+ -- PS.EXCM = 0, C calling enabled
+
+ NOTE: For CALL0 ABI, a12-a15 have not yet been saved.
+
+ NOTE: This macro will use registers a0 and a2-a6. The arguments are:
+ level -- interrupt level
+ mask -- interrupt bitmask for this level
+--------------------------------------------------------------------------------
+*/
+
+ .macro dispatch_c_isr level mask
+
+ /* Get mask of pending, enabled interrupts at this level into a2. */
+
+.L_xt_user_int_&level&:
+ rsr a2, INTENABLE
+ rsr a3, INTERRUPT
+ movi a4, \mask
+ and a2, a2, a3
+ and a2, a2, a4
+ beqz a2, 9f /* nothing to do */
+
+ /* This bit of code provides a nice debug backtrace in the debugger.
+ It does take a few more instructions, so undef XT_DEBUG_BACKTRACE
+ if you want to save the cycles.
+ */
+ #if XT_DEBUG_BACKTRACE
+ #ifndef __XTENSA_CALL0_ABI__
+ rsr a0, EPC_1 + \level - 1 /* return address */
+ movi a4, 0xC0000000 /* constant with top 2 bits set (call size) */
+ or a0, a0, a4 /* set top 2 bits */
+ addx2 a0, a4, a0 /* clear top bit -- simulating call4 size */
+ #endif
+ #endif
+
+ #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+ /* Call the ISR enter function to indicate an ISR is executing. */
+ #ifdef __XTENSA_CALL0_ABI__
+ call0 _tx_execution_isr_enter
+ #else
+ call4 _tx_execution_isr_enter
+ #endif
+ #endif
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a4, _xt_intexc_hooks
+ l32i a4, a4, \level << 2
+ beqz a4, 2f
+ #ifdef __XTENSA_CALL0_ABI__
+ callx0 a4
+ beqz a2, 9f
+ #else
+ mov a6, a2
+ callx4 a4
+ beqz a6, 9f
+ mov a2, a6
+ #endif
+2:
+ #endif
+
+ /* Now look up in the dispatch table and call user ISR if any. */
+ /* If multiple bits are set then MSB has highest priority. */
+
+ extract_msb a4, a2 /* a4 = MSB of a2, a2 trashed */
+
+ #ifdef XT_USE_SWPRI
+ /* Enable all interrupts at this level that are numerically higher
+ than the one we just selected, since they are treated as higher
+ priority.
+ */
+ movi a3, \mask /* a3 = all interrupts at this level */
+ add a2, a4, a4 /* a2 = a4 << 1 */
+ addi a2, a2, -1 /* a2 = mask of 1's <= a4 bit */
+ and a2, a2, a3 /* a2 = mask of all bits <= a4 at this level */
+ movi a3, _xt_intdata
+ l32i a6, a3, 4 /* a6 = _xt_vpri_mask */
+ neg a2, a2
+ addi a2, a2, -1 /* a2 = mask to apply */
+ and a5, a6, a2 /* mask off all bits <= a4 bit */
+ s32i a5, a3, 4 /* update _xt_vpri_mask */
+ rsr a3, INTENABLE
+ and a3, a3, a2 /* mask off all bits <= a4 bit */
+ wsr a3, INTENABLE
+ rsil a3, \level - 1 /* lower interrupt level by 1 */
+ #endif
+
+ wsr a4, INTCLEAR /* clear sw or edge-triggered interrupt */
+
+ #ifndef TX_NO_TIMER
+ movi a3, XT_TIMER_INTEN /* a3 = timer interrupt bit */
+ beq a3, a4, 7f /* if timer interrupt then skip table */
+ #endif
+
+ find_ms_setbit a3, a4, a3, 0 /* a3 = interrupt number */
+
+ movi a4, _xt_interrupt_table
+ addx8 a3, a3, a4 /* a3 = address of interrupt table entry */
+ l32i a4, a3, XIE_HANDLER /* a4 = handler address */
+ #ifdef __XTENSA_CALL0_ABI__
+ mov a12, a6 /* save in callee-saved reg */
+ l32i a2, a3, XIE_ARG /* a2 = handler arg */
+ callx0 a4 /* call handler */
+ mov a2, a12
+ #else
+ mov a2, a6 /* save in windowed reg */
+ l32i a6, a3, XIE_ARG /* a6 = handler arg */
+ callx4 a4 /* call handler */
+ #endif
+
+ #ifdef XT_USE_SWPRI
+ j 8f
+ #else
+ j .L_xt_user_int_&level& /* check for more interrupts */
+ #endif
+
+7:
+
+ #ifndef TX_NO_TIMER
+ .ifeq XT_TIMER_INTPRI - \level
+.L_xt_user_int_timer_&level&:
+ /*
+ Interrupt handler for the RTOS tick timer if at this level.
+ We'll be reading the interrupt state again after this call
+ so no need to preserve any registers except a6 (vpri_mask).
+ */
+
+ #ifdef __XTENSA_CALL0_ABI__
+ mov a12, a6
+ call0 XT_RTOS_TIMER_INT
+ mov a2, a12
+ #else
+ mov a2, a6
+ call4 XT_RTOS_TIMER_INT
+ #endif
+ .endif
+ #endif
+
+ #ifdef XT_USE_SWPRI
+ j 8f
+ #else
+ j .L_xt_user_int_&level& /* check for more interrupts */
+ #endif
+
+ #ifdef XT_USE_SWPRI
+8:
+ /*
+ Restore old value of _xt_vpri_mask from a2. Also update INTENABLE from
+ virtual _xt_intenable which _could_ have changed during interrupt
+ processing. But before that, raise the interrupt level back again.
+ */
+
+ rsil a3, \level
+ movi a3, _xt_intdata
+ l32i a4, a3, 0 /* a4 = _xt_intenable */
+ s32i a2, a3, 4 /* update _xt_vpri_mask */
+ and a4, a4, a2 /* a4 = masked intenable */
+ wsr a4, INTENABLE /* update INTENABLE */
+ #endif
+
+9:
+ /* done */
+
+ #if XCHAL_HAVE_EXCLUSIVE
+ /* Clear any local exclusive monitors. */
+ clrex
+ #endif
+
+ .endm
+
+
+/*
+--------------------------------------------------------------------------------
+ Panic handler.
+ Should be reached by call0 (preferable) or jump only. If call0, a0 says where
+ from. If on simulator, display panic message and abort, else loop indefinitely.
+--------------------------------------------------------------------------------
+*/
+
+ .text
+ .global _xt_panic
+ .type _xt_panic,@function
+ .align 4
+
+_xt_panic:
+ #ifdef XT_SIMULATOR
+ addi a4, a0, -3 /* point to call0 */
+ movi a3, _xt_panic_message
+ movi a2, SYS_log_msg
+ simcall
+ movi a2, SYS_gdb_abort
+ simcall
+ #else
+ rsil a2, XCHAL_EXCM_LEVEL /* disable all low & med ints */
+1: j 1b /* loop infinitely */
+ #endif
+
+ .section .rodata, "a"
+ .align 4
+
+_xt_panic_message:
+ .string "\n*** _xt_panic() was called from 0x%08x or jumped to. ***\n"
+
+
+/*
+--------------------------------------------------------------------------------
+ Hooks to dynamically install handlers for exceptions and interrupts.
+ Allows automated regression frameworks to install handlers per test.
+ Consists of an array of function pointers indexed by interrupt level,
+ with index 0 containing the entry for user exceptions.
+ Initialized with all 0s, meaning no handler is installed at each level.
+ See comment in xtensa_rtos.h for more details.
+--------------------------------------------------------------------------------
+*/
+
+ #ifdef XT_INTEXC_HOOKS
+ .data
+ .global _xt_intexc_hooks
+ .type _xt_intexc_hooks,@object
+ .align 4
+
+_xt_intexc_hooks:
+ .fill XT_INTEXC_HOOK_NUM, 4, 0
+ #endif
+
+
+/*
+--------------------------------------------------------------------------------
+ EXCEPTION AND LEVEL 1 INTERRUPT VECTORS AND LOW LEVEL HANDLERS
+ (except window exception vectors).
+
+ Each vector goes at a predetermined location according to the Xtensa
+ hardware configuration, which is ensured by its placement in a special
+ section known to the Xtensa linker support package (LSP). It performs
+ the minimum necessary before jumping to the handler in the .text section.
+
+ The corresponding handler goes in the normal .text section. It sets up
+ the appropriate stack frame, saves a few vector-specific registers and
+ calls XT_RTOS_INT_ENTER to save the rest of the interrupted context
+ and enter the RTOS, then sets up a C environment. It then calls the
+ user's interrupt handler code (which may be coded in C) and finally
+ calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling.
+
+ While XT_RTOS_INT_EXIT does not return directly to the interruptee,
+ eventually the RTOS scheduler will want to dispatch the interrupted
+ task or handler. The scheduler will return to the exit point that was
+ saved in the interrupt stack frame at XT_STK_EXIT.
+--------------------------------------------------------------------------------
+*/
+
+
+/*
+--------------------------------------------------------------------------------
+Debug Exception.
+--------------------------------------------------------------------------------
+*/
+
+#if XCHAL_HAVE_DEBUG
+
+ .begin literal_prefix .DebugExceptionVector
+ .section .DebugExceptionVector.text, "ax"
+ .global _DebugExceptionVector
+ .align 4
+
+_DebugExceptionVector:
+
+ #ifdef XT_SIMULATOR
+ /*
+ In the simulator, let the debugger (if any) handle the debug exception,
+ or simply stop the simulation:
+ */
+ wsr a2, EXCSAVE+XCHAL_DEBUGLEVEL /* save a2 where sim expects it */
+ movi a2, SYS_gdb_enter_sktloop
+ simcall /* have ISS handle debug exc. */
+ #elif 0 /* change condition to 1 to use the HAL minimal debug handler */
+ wsr a3, EXCSAVE+XCHAL_DEBUGLEVEL
+ movi a3, xthal_debugexc_defhndlr_nw /* use default debug handler */
+ jx a3
+ #else
+ wsr a0, EXCSAVE+XCHAL_DEBUGLEVEL /* save original a0 somewhere */
+ call0 _xt_panic /* does not return */
+ rfi XCHAL_DEBUGLEVEL /* make a0 point here not later */
+ #endif
+
+ .end literal_prefix
+
+#endif
+
+/*
+--------------------------------------------------------------------------------
+Double Exception.
+Double exceptions are not a normal occurrence. They indicate a bug of some kind.
+--------------------------------------------------------------------------------
+*/
+
+#ifdef XCHAL_DOUBLEEXC_VECTOR_VADDR
+
+ .begin literal_prefix .DoubleExceptionVector
+ .section .DoubleExceptionVector.text, "ax"
+ .global _DoubleExceptionVector
+ .align 4
+
+_DoubleExceptionVector:
+
+ #if XCHAL_HAVE_DEBUG
+ break 1, 4 /* unhandled double exception */
+ #endif
+ call0 _xt_panic /* does not return */
+ rfde /* make a0 point here not later */
+
+ .end literal_prefix
+
+#endif /* XCHAL_DOUBLEEXC_VECTOR_VADDR */
+
+/*
+--------------------------------------------------------------------------------
+Kernel Exception (including Level 1 Interrupt from kernel mode).
+--------------------------------------------------------------------------------
+*/
+
+ .begin literal_prefix .KernelExceptionVector
+ .section .KernelExceptionVector.text, "ax"
+ .global _KernelExceptionVector
+ .align 4
+
+_KernelExceptionVector:
+
+ wsr a0, EXCSAVE_1 /* preserve a0 */
+ call0 _xt_kernel_exc /* kernel exception handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .align 4
+
+_xt_kernel_exc:
+ #if XCHAL_HAVE_DEBUG
+ break 1, 0 /* unhandled kernel exception */
+ #endif
+ call0 _xt_panic /* does not return */
+ rfe /* make a0 point here not there */
+
+
+/*
+--------------------------------------------------------------------------------
+User Exception (including Level 1 Interrupt from user mode).
+--------------------------------------------------------------------------------
+*/
+
+ .begin literal_prefix .UserExceptionVector
+ .section .UserExceptionVector.text, "ax"
+ .global _UserExceptionVector
+ .type _UserExceptionVector,@function
+ .align 4
+
+_UserExceptionVector:
+
+ wsr a0, EXCSAVE_1 /* preserve a0 */
+ call0 _xt_user_exc /* user exception handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+/*
+--------------------------------------------------------------------------------
+ Insert some waypoints for jumping beyond the signed 8-bit range of
+ conditional branch instructions, so the conditional branchces to specific
+ exception handlers are not taken in the mainline. Saves some cycles in the
+ mainline.
+--------------------------------------------------------------------------------
+*/
+
+ .text
+
+ #if XCHAL_HAVE_WINDOWED
+ .align 4
+_xt_to_alloca_exc:
+ call0 _xt_alloca_exc /* in window vectors section */
+ /* never returns here - call0 is used as a jump (see note at top) */
+ #endif
+
+ .align 4
+_xt_to_syscall_exc:
+ call0 _xt_syscall_exc
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ #if XCHAL_CP_NUM > 0
+ .align 4
+_xt_to_coproc_exc:
+ call0 _xt_coproc_exc
+ /* never returns here - call0 is used as a jump (see note at top) */
+ #endif
+
+
+/*
+--------------------------------------------------------------------------------
+ User exception handler.
+--------------------------------------------------------------------------------
+*/
+
+ .type _xt_user_exc,@function
+ .align 4
+
+_xt_user_exc:
+
+ /* If level 1 interrupt then jump to the dispatcher */
+ rsr a0, EXCCAUSE
+ beqi a0, EXCCAUSE_LEVEL1_INTERRUPT, _xt_lowint1
+
+ /* Handle any coprocessor exceptions. Rely on the fact that exception
+ numbers above EXCCAUSE_CP0_DISABLED all relate to the coprocessors.
+ */
+ #if XCHAL_CP_NUM > 0
+ bgeui a0, EXCCAUSE_CP0_DISABLED, _xt_to_coproc_exc
+ #endif
+
+ /* Handle alloca and syscall exceptions */
+ #if XCHAL_HAVE_WINDOWED
+ beqi a0, EXCCAUSE_ALLOCA, _xt_to_alloca_exc
+ #endif
+ beqi a0, EXCCAUSE_SYSCALL, _xt_to_syscall_exc
+
+ /* Handle all other exceptions. All can have user-defined handlers. */
+ /* NOTE: we'll stay on the user stack for exception handling. */
+
+ /* Allocate exception frame and save minimal context. */
+ mov a0, sp
+ addi sp, sp, -XT_STK_FRMSZ
+ s32i a0, sp, XT_STK_A1
+ #if XCHAL_HAVE_WINDOWED
+ s32e a0, sp, -12 /* for debug backtrace */
+ #endif
+ rsr a0, PS /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_1 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_1 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ #if XCHAL_HAVE_WINDOWED
+ s32e a0, sp, -16 /* for debug backtrace */
+ #endif
+ s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */
+ s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */
+ call0 _xt_context_save
+
+ /* Save exc cause and vaddr into exception frame */
+ rsr a0, EXCCAUSE
+ s32i a0, sp, XT_STK_EXCCAUSE
+ rsr a0, EXCVADDR
+ s32i a0, sp, XT_STK_EXCVADDR
+
+ /* Set up PS for C, reenable hi-pri interrupts, and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+
+ #ifdef XT_DEBUG_BACKTRACE
+ #ifndef __XTENSA_CALL0_ABI__
+ rsr a0, EPC_1 /* return address for debug backtrace */
+ movi a5, 0xC0000000 /* constant with top 2 bits set (call size) */
+ rsync /* wait for WSR.PS to complete */
+ or a0, a0, a5 /* set top 2 bits */
+ addx2 a0, a5, a0 /* clear top bit -- thus simulating call4 size */
+ #else
+ rsync /* wait for WSR.PS to complete */
+ #endif
+ #endif
+
+ rsr a2, EXCCAUSE /* recover exc cause */
+
+ #ifdef XT_INTEXC_HOOKS
+ /*
+ Call exception hook to pre-handle exceptions (if installed).
+ Pass EXCCAUSE in a2, and check result in a2 (if -1, skip default handling).
+ */
+ movi a4, _xt_intexc_hooks
+ l32i a4, a4, 0 /* user exception hook index 0 */
+ beqz a4, 1f
+.Ln_xt_user_exc_call_hook:
+ #ifdef __XTENSA_CALL0_ABI__
+ callx0 a4
+ beqi a2, -1, .L_xt_user_done
+ #else
+ mov a6, a2
+ callx4 a4
+ beqi a6, -1, .L_xt_user_done
+ mov a2, a6
+ #endif
+1:
+ #endif
+
+ rsr a2, EXCCAUSE /* recover exc cause */
+ movi a3, _xt_exception_table
+ addx4 a4, a2, a3 /* a4 = address of exception table entry */
+ l32i a4, a4, 0 /* a4 = handler address */
+ #ifdef __XTENSA_CALL0_ABI__
+ mov a2, sp /* a2 = pointer to exc frame */
+ callx0 a4 /* call handler */
+ #else
+ mov a6, sp /* a6 = pointer to exc frame */
+ callx4 a4 /* call handler */
+ #endif
+
+.L_xt_user_done:
+
+ /* Restore context and return */
+ call0 _xt_context_restore
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, PS
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_1
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove exception frame */
+ rsync /* ensure PS and EPC written */
+ rfe /* PS.EXCM is cleared */
+
+
+/*
+--------------------------------------------------------------------------------
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+--------------------------------------------------------------------------------
+*/
+
+ .global _xt_user_exit
+ .type _xt_user_exit,@function
+ .align 4
+_xt_user_exit:
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, PS
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_1
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure PS and EPC written */
+ rfe /* PS.EXCM is cleared */
+
+
+/*
+--------------------------------------------------------------------------------
+Syscall Exception Handler (jumped to from User Exception Handler).
+Syscall 0 is required to spill the register windows (no-op in Call 0 ABI).
+Only syscall 0 is handled here. Other syscalls return -1 to caller in a2.
+--------------------------------------------------------------------------------
+*/
+
+ .text
+ .type _xt_syscall_exc,@function
+ .align 4
+_xt_syscall_exc:
+
+ #ifdef __XTENSA_CALL0_ABI__
+ /*
+ Save minimal regs for scratch. Syscall 0 does nothing in Call0 ABI.
+ Use a minimal stack frame (16B) to save A2 & A3 for scratch.
+ PS.EXCM could be cleared here, but unlikely to improve worst-case latency.
+ rsr a0, PS
+ addi a0, a0, -PS_EXCM_MASK
+ wsr a0, PS
+ */
+ addi sp, sp, -16
+ s32i a2, sp, 8
+ s32i a3, sp, 12
+ #else /* Windowed ABI */
+ /*
+ Save necessary context and spill the register windows.
+ PS.EXCM is still set and must remain set until after the spill.
+ Reuse context save function though it saves more than necessary.
+ For this reason, a full interrupt stack frame is allocated.
+ */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a12, sp, XT_STK_A12 /* _xt_context_save requires A12- */
+ s32i a13, sp, XT_STK_A13 /* A13 to have already been saved */
+ call0 _xt_context_save
+ #endif
+
+ /*
+ Grab the interruptee's PC and skip over the 'syscall' instruction.
+ If it's at the end of a zero-overhead loop and it's not on the last
+ iteration, decrement loop counter and skip to beginning of loop.
+ */
+ rsr a2, EPC_1 /* a2 = PC of 'syscall' */
+ addi a3, a2, 3 /* ++PC */
+ #if XCHAL_HAVE_LOOPS
+ rsr a0, LEND /* if (PC == LEND */
+ bne a3, a0, 1f
+ rsr a0, LCOUNT /* && LCOUNT != 0) */
+ beqz a0, 1f /* { */
+ addi a0, a0, -1 /* --LCOUNT */
+ rsr a3, LBEG /* PC = LBEG */
+ wsr a0, LCOUNT /* } */
+ #endif
+1: wsr a3, EPC_1 /* update PC */
+
+ /* Restore interruptee's context and return from exception. */
+ #ifdef __XTENSA_CALL0_ABI__
+ l32i a2, sp, 8
+ l32i a3, sp, 12
+ addi sp, sp, 16
+ #else
+ call0 _xt_context_restore
+ addi sp, sp, XT_STK_FRMSZ
+ #endif
+ movi a0, -1
+ movnez a2, a0, a2 /* return -1 if not syscall 0 */
+ rsr a0, EXCSAVE_1
+ rfe
+
+
+/*
+-------------------------------------------------------------------------------
+ Level 1 interrupt dispatch. Assumes stack frame has not been allocated yet.
+-------------------------------------------------------------------------------
+*/
+
+ .text
+ .type _xt_lowint1,@function
+ .align 4
+
+_xt_lowint1:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, PS /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_1 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_1 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_user_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(1) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(1) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 1 XCHAL_INTLEVEL1_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+
+/*
+-------------------------------------------------------------------------------
+ MEDIUM PRIORITY (LEVEL 2+) INTERRUPT VECTORS AND LOW LEVEL HANDLERS.
+
+ Medium priority interrupts are by definition those with priority greater
+ than 1 and not greater than XCHAL_EXCM_LEVEL. These are disabled by
+ setting PS.EXCM and therefore can easily support a C environment for
+ handlers in C, and interact safely with an RTOS.
+
+ Each vector goes at a predetermined location according to the Xtensa
+ hardware configuration, which is ensured by its placement in a special
+ section known to the Xtensa linker support package (LSP). It performs
+ the minimum necessary before jumping to the handler in the .text section.
+
+ The corresponding handler goes in the normal .text section. It sets up
+ the appropriate stack frame, saves a few vector-specific registers and
+ calls XT_RTOS_INT_ENTER to save the rest of the interrupted context
+ and enter the RTOS, then sets up a C environment. It then calls the
+ user's interrupt handler code (which may be coded in C) and finally
+ calls XT_RTOS_INT_EXIT to transfer control to the RTOS for scheduling.
+
+ While XT_RTOS_INT_EXIT does not return directly to the interruptee,
+ eventually the RTOS scheduler will want to dispatch the interrupted
+ task or handler. The scheduler will return to the exit point that was
+ saved in the interrupt stack frame at XT_STK_EXIT.
+-------------------------------------------------------------------------------
+*/
+
+#if XCHAL_EXCM_LEVEL >= 2
+
+ .begin literal_prefix .Level2InterruptVector
+ .section .Level2InterruptVector.text, "ax"
+ .global _Level2Vector
+ .type _Level2Vector,@function
+ .align 4
+_Level2Vector:
+ wsr a0, EXCSAVE_2 /* preserve a0 */
+ call0 _xt_medint2 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_medint2,@function
+ .align 4
+_xt_medint2:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, EPS_2 /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_2 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_2 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_medint2_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(2) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(2) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 2 XCHAL_INTLEVEL2_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+ /*
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+ */
+ .global _xt_medint2_exit
+ .type _xt_medint2_exit,@function
+ .align 4
+_xt_medint2_exit:
+ /* Restore only level-specific regs (the rest were already restored) */
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, EPS_2
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_2
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure EPS and EPC written */
+ rfi 2
+
+#endif /* Level 2 */
+
+#if XCHAL_EXCM_LEVEL >= 3
+
+ .begin literal_prefix .Level3InterruptVector
+ .section .Level3InterruptVector.text, "ax"
+ .global _Level3Vector
+ .type _Level3Vector,@function
+ .align 4
+_Level3Vector:
+ wsr a0, EXCSAVE_3 /* preserve a0 */
+ call0 _xt_medint3 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_medint3,@function
+ .align 4
+_xt_medint3:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, EPS_3 /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_3 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_3 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_medint3_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(3) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(3) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 3 XCHAL_INTLEVEL3_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+ /*
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+ */
+ .global _xt_medint3_exit
+ .type _xt_medint3_exit,@function
+ .align 4
+_xt_medint3_exit:
+ /* Restore only level-specific regs (the rest were already restored) */
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, EPS_3
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_3
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure EPS and EPC written */
+ rfi 3
+
+#endif /* Level 3 */
+
+#if XCHAL_EXCM_LEVEL >= 4
+
+ .begin literal_prefix .Level4InterruptVector
+ .section .Level4InterruptVector.text, "ax"
+ .global _Level4Vector
+ .type _Level4Vector,@function
+ .align 4
+_Level4Vector:
+ wsr a0, EXCSAVE_4 /* preserve a0 */
+ call0 _xt_medint4 /* load interrupt handler */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_medint4,@function
+ .align 4
+_xt_medint4:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, EPS_4 /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_4 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_4 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_medint4_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(4) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(4) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 4 XCHAL_INTLEVEL4_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+ /*
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+ */
+ .global _xt_medint4_exit
+ .type _xt_medint4_exit,@function
+ .align 4
+_xt_medint4_exit:
+ /* Restore only level-specific regs (the rest were already restored) */
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, EPS_4
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_4
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure EPS and EPC written */
+ rfi 4
+
+#endif /* Level 4 */
+
+#if XCHAL_EXCM_LEVEL >= 5
+
+ .begin literal_prefix .Level5InterruptVector
+ .section .Level5InterruptVector.text, "ax"
+ .global _Level5Vector
+ .type _Level5Vector,@function
+ .align 4
+_Level5Vector:
+ wsr a0, EXCSAVE_5 /* preserve a0 */
+ call0 _xt_medint5 /* load interrupt handler */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_medint5,@function
+ .align 4
+_xt_medint5:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, EPS_5 /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_5 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_5 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_medint5_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(5) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(5) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 5 XCHAL_INTLEVEL5_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+ /*
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+ */
+ .global _xt_medint5_exit
+ .type _xt_medint5_exit,@function
+ .align 4
+_xt_medint5_exit:
+ /* Restore only level-specific regs (the rest were already restored) */
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, EPS_5
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_5
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure EPS and EPC written */
+ rfi 5
+
+#endif /* Level 5 */
+
+#if XCHAL_EXCM_LEVEL >= 6
+
+ .begin literal_prefix .Level6InterruptVector
+ .section .Level6InterruptVector.text, "ax"
+ .global _Level6Vector
+ .type _Level6Vector,@function
+ .align 4
+_Level6Vector:
+ wsr a0, EXCSAVE_6 /* preserve a0 */
+ call0 _xt_medint6 /* load interrupt handler */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_medint6,@function
+ .align 4
+_xt_medint6:
+ mov a0, sp /* sp == a1 */
+ addi sp, sp, -XT_STK_FRMSZ /* allocate interrupt stack frame */
+ s32i a0, sp, XT_STK_A1 /* save pre-interrupt SP */
+ rsr a0, EPS_6 /* save interruptee's PS */
+ s32i a0, sp, XT_STK_PS
+ rsr a0, EPC_6 /* save interruptee's PC */
+ s32i a0, sp, XT_STK_PC
+ rsr a0, EXCSAVE_6 /* save interruptee's a0 */
+ s32i a0, sp, XT_STK_A0
+ movi a0, _xt_medint6_exit /* save exit point for dispatch */
+ s32i a0, sp, XT_STK_EXIT
+
+ /* Save rest of interrupt context and enter RTOS. */
+ call0 XT_RTOS_INT_ENTER /* common RTOS interrupt entry */
+
+ /* !! We are now on the RTOS system stack !! */
+
+ /* Set up PS for C, enable interrupts above this level and clear EXCM. */
+ #ifdef __XTENSA_CALL0_ABI__
+ movi a0, PS_INTLEVEL(6) | PS_UM
+ #else
+ movi a0, PS_INTLEVEL(6) | PS_UM | PS_WOE
+ #endif
+ wsr a0, PS
+ rsync
+
+ /* OK to call C code at this point, dispatch user ISRs */
+
+ dispatch_c_isr 6 XCHAL_INTLEVEL6_MASK
+
+ /* Done handling interrupts, transfer control to OS */
+ call0 XT_RTOS_INT_EXIT /* does not return directly here */
+
+ /*
+ Exit point for dispatch. Saved in interrupt stack frame at XT_STK_EXIT
+ on entry and used to return to a thread or interrupted interrupt handler.
+ */
+ .global _xt_medint6_exit
+ .type _xt_medint6_exit,@function
+ .align 4
+_xt_medint6_exit:
+ /* Restore only level-specific regs (the rest were already restored) */
+ l32i a0, sp, XT_STK_PS /* retrieve interruptee's PS */
+ wsr a0, EPS_6
+ l32i a0, sp, XT_STK_PC /* retrieve interruptee's PC */
+ wsr a0, EPC_6
+ l32i a0, sp, XT_STK_A0 /* retrieve interruptee's A0 */
+ l32i sp, sp, XT_STK_A1 /* remove interrupt stack frame */
+ rsync /* ensure EPS and EPC written */
+ rfi 6
+
+#endif /* Level 6 */
+
+
+/*******************************************************************************
+
+HIGH PRIORITY (LEVEL > XCHAL_EXCM_LEVEL) INTERRUPT VECTORS AND HANDLERS
+
+High priority interrupts are by definition those with priorities greater
+than XCHAL_EXCM_LEVEL. This includes non-maskable (NMI). High priority
+interrupts cannot interact with the RTOS, that is they must save all regs
+they use and not call any RTOS function.
+
+A further restriction imposed by the Xtensa windowed architecture is that
+high priority interrupts must not modify the stack area even logically
+"above" the top of the interrupted stack (they need to provide their
+own stack or static save area).
+
+Cadence Design Systems recommends high priority interrupt handlers be coded in assembly
+and used for purposes requiring very short service times.
+
+Here are templates for high priority (level 2+) interrupt vectors.
+They assume only one interrupt per level to avoid the burden of identifying
+which interrupts at this level are pending and enabled. This allows for
+minimum latency and avoids having to save/restore a2 in addition to a0.
+If more than one interrupt per high priority level is configured, this burden
+is on the handler which in any case must provide a way to save and restore
+registers it uses without touching the interrupted stack.
+
+Each vector goes at a predetermined location according to the Xtensa
+hardware configuration, which is ensured by its placement in a special
+section known to the Xtensa linker support package (LSP). It performs
+the minimum necessary before jumping to the handler in the .text section.
+
+*******************************************************************************/
+
+/*
+Currently only shells for high priority interrupt handlers are provided
+here. However a template and example can be found in the Cadence Design Systems tools
+documentation: "Microprocessor Programmer's Guide".
+*/
+
+#if XCHAL_NUM_INTLEVELS >=2 && XCHAL_EXCM_LEVEL <2 && XCHAL_DEBUGLEVEL !=2
+
+ .begin literal_prefix .Level2InterruptVector
+ .section .Level2InterruptVector.text, "ax"
+ .global _Level2Vector
+ .type _Level2Vector,@function
+ .align 4
+_Level2Vector:
+ wsr a0, EXCSAVE_2 /* preserve a0 */
+ call0 _xt_highint2 /* load interrupt handler */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_highint2,@function
+ .align 4
+_xt_highint2:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, 2<<2
+ beqz a0, 1f
+.Ln_xt_highint2_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY LEVEL 2 INTERRUPT HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_highint2_exit:
+ rsr a0, EXCSAVE_2 /* restore a0 */
+ rfi 2
+
+#endif /* Level 2 */
+
+#if XCHAL_NUM_INTLEVELS >=3 && XCHAL_EXCM_LEVEL <3 && XCHAL_DEBUGLEVEL !=3
+
+ .begin literal_prefix .Level3InterruptVector
+ .section .Level3InterruptVector.text, "ax"
+ .global _Level3Vector
+ .type _Level3Vector,@function
+ .align 4
+_Level3Vector:
+ wsr a0, EXCSAVE_3 /* preserve a0 */
+ call0 _xt_highint3 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_highint3,@function
+ .align 4
+_xt_highint3:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, 3<<2
+ beqz a0, 1f
+.Ln_xt_highint3_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY LEVEL 3 INTERRUPT HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_highint3_exit:
+ rsr a0, EXCSAVE_3 /* restore a0 */
+ rfi 3
+
+#endif /* Level 3 */
+
+#if XCHAL_NUM_INTLEVELS >=4 && XCHAL_EXCM_LEVEL <4 && XCHAL_DEBUGLEVEL !=4
+
+ .begin literal_prefix .Level4InterruptVector
+ .section .Level4InterruptVector.text, "ax"
+ .global _Level4Vector
+ .type _Level4Vector,@function
+ .align 4
+_Level4Vector:
+ wsr a0, EXCSAVE_4 /* preserve a0 */
+ call0 _xt_highint4 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_highint4,@function
+ .align 4
+_xt_highint4:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, 4<<2
+ beqz a0, 1f
+.Ln_xt_highint4_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY LEVEL 4 INTERRUPT HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_highint4_exit:
+ rsr a0, EXCSAVE_4 /* restore a0 */
+ rfi 4
+
+#endif /* Level 4 */
+
+#if XCHAL_NUM_INTLEVELS >=5 && XCHAL_EXCM_LEVEL <5 && XCHAL_DEBUGLEVEL !=5
+
+ .begin literal_prefix .Level5InterruptVector
+ .section .Level5InterruptVector.text, "ax"
+ .global _Level5Vector
+ .type _Level5Vector,@function
+ .align 4
+_Level5Vector:
+ wsr a0, EXCSAVE_5 /* preserve a0 */
+ call0 _xt_highint5 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_highint5,@function
+ .align 4
+_xt_highint5:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, 5<<2
+ beqz a0, 1f
+.Ln_xt_highint5_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY LEVEL 5 INTERRUPT HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_highint5_exit:
+ rsr a0, EXCSAVE_5 /* restore a0 */
+ rfi 5
+
+#endif /* Level 5 */
+
+#if XCHAL_NUM_INTLEVELS >=6 && XCHAL_EXCM_LEVEL <6 && XCHAL_DEBUGLEVEL !=6
+
+ .begin literal_prefix .Level6InterruptVector
+ .section .Level6InterruptVector.text, "ax"
+ .global _Level6Vector
+ .type _Level6Vector,@function
+ .align 4
+_Level6Vector:
+ wsr a0, EXCSAVE_6 /* preserve a0 */
+ call0 _xt_highint6 /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_highint6,@function
+ .align 4
+_xt_highint6:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, 6<<2
+ beqz a0, 1f
+.Ln_xt_highint6_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY LEVEL 6 INTERRUPT HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_highint6_exit:
+ rsr a0, EXCSAVE_6 /* restore a0 */
+ rfi 6
+
+#endif /* Level 6 */
+
+#if XCHAL_HAVE_NMI
+
+ .begin literal_prefix .NMIExceptionVector
+ .section .NMIExceptionVector.text, "ax"
+ .global _NMIExceptionVector
+ .type _NMIExceptionVector,@function
+ .align 4
+_NMIExceptionVector:
+ wsr a0, EXCSAVE + XCHAL_NMILEVEL _ /* preserve a0 */
+ call0 _xt_nmi /* load interrupt handler */
+ /* never returns here - call0 is used as a jump (see note at top) */
+
+ .end literal_prefix
+
+ .text
+ .type _xt_nmi,@function
+ .align 4
+_xt_nmi:
+
+ #ifdef XT_INTEXC_HOOKS
+ /* Call interrupt hook if present to (pre)handle interrupts. */
+ movi a0, _xt_intexc_hooks
+ l32i a0, a0, XCHAL_NMILEVEL<<2
+ beqz a0, 1f
+.Ln_xt_nmi_call_hook:
+ callx0 a0 /* must NOT disturb stack! */
+1:
+ #endif
+
+ /* USER_EDIT:
+ ADD HIGH PRIORITY NON-MASKABLE INTERRUPT (NMI) HANDLER CODE HERE.
+ */
+
+ .align 4
+.L_xt_nmi_exit:
+ rsr a0, EXCSAVE + XCHAL_NMILEVEL /* restore a0 */
+ rfi XCHAL_NMILEVEL
+
+#endif /* NMI */
+
+
+/*******************************************************************************
+
+WINDOW OVERFLOW AND UNDERFLOW EXCEPTION VECTORS AND ALLOCA EXCEPTION HANDLER
+
+Here is the code for each window overflow/underflow exception vector and
+(interspersed) efficient code for handling the alloca exception cause.
+Window exceptions are handled entirely in the vector area and are very
+tight for performance. The alloca exception is also handled entirely in
+the window vector area so comes at essentially no cost in code size.
+Users should never need to modify them and Cadence Design Systems recommends
+they do not.
+
+Window handlers go at predetermined vector locations according to the
+Xtensa hardware configuration, which is ensured by their placement in a
+special section known to the Xtensa linker support package (LSP). Since
+their offsets in that section are always the same, the LSPs do not define
+a section per vector.
+
+These things are coded for XEA2 only (XEA1 is not supported).
+
+Note on Underflow Handlers:
+The underflow handler for returning from call[i+1] to call[i]
+must preserve all the registers from call[i+1]'s window.
+In particular, a0 and a1 must be preserved because the RETW instruction
+will be reexecuted (and may even underflow if an intervening exception
+has flushed call[i]'s registers).
+Registers a2 and up may contain return values.
+
+*******************************************************************************/
+
+#if XCHAL_HAVE_WINDOWED
+
+ .section .WindowVectors.text, "ax"
+
+/*
+--------------------------------------------------------------------------------
+Window Overflow Exception for Call4.
+
+Invoked if a call[i] referenced a register (a4-a15)
+that contains data from ancestor call[j];
+call[j] had done a call4 to call[j+1].
+On entry here:
+ window rotated to call[j] start point;
+ a0-a3 are registers to be saved;
+ a4-a15 must be preserved;
+ a5 is call[j+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0x0
+ .global _WindowOverflow4
+_WindowOverflow4:
+
+ s32e a0, a5, -16 /* save a0 to call[j+1]'s stack frame */
+ s32e a1, a5, -12 /* save a1 to call[j+1]'s stack frame */
+ s32e a2, a5, -8 /* save a2 to call[j+1]'s stack frame */
+ s32e a3, a5, -4 /* save a3 to call[j+1]'s stack frame */
+ rfwo /* rotates back to call[i] position */
+
+/*
+--------------------------------------------------------------------------------
+Window Underflow Exception for Call4
+
+Invoked by RETW returning from call[i+1] to call[i]
+where call[i]'s registers must be reloaded (not live in ARs);
+where call[i] had done a call4 to call[i+1].
+On entry here:
+ window rotated to call[i] start point;
+ a0-a3 are undefined, must be reloaded with call[i].reg[0..3];
+ a4-a15 must be preserved (they are call[i+1].reg[0..11]);
+ a5 is call[i+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0x40
+ .global _WindowUnderflow4
+_WindowUnderflow4:
+
+ l32e a0, a5, -16 /* restore a0 from call[i+1]'s stack frame */
+ l32e a1, a5, -12 /* restore a1 from call[i+1]'s stack frame */
+ l32e a2, a5, -8 /* restore a2 from call[i+1]'s stack frame */
+ l32e a3, a5, -4 /* restore a3 from call[i+1]'s stack frame */
+ rfwu
+
+/*
+--------------------------------------------------------------------------------
+Handle alloca exception generated by interruptee executing 'movsp'.
+This uses space between the window vectors, so is essentially "free".
+All interruptee's regs are intact except a0 which is saved in EXCSAVE_1,
+and PS.EXCM has been set by the exception hardware (can't be interrupted).
+The fact the alloca exception was taken means the registers associated with
+the base-save area have been spilled and will be restored by the underflow
+handler, so those 4 registers are available for scratch.
+The code is optimized to avoid unaligned branches and minimize cache misses.
+--------------------------------------------------------------------------------
+*/
+
+ .align 4
+ .global _xt_alloca_exc
+_xt_alloca_exc:
+
+ rsr a0, WINDOWBASE /* grab WINDOWBASE before rotw changes it */
+ rotw -1 /* WINDOWBASE goes to a4, new a0-a3 are scratch */
+ rsr a2, PS
+ extui a3, a2, PS_OWB_SHIFT, PS_OWB_BITS
+ xor a3, a3, a4 /* bits changed from old to current windowbase */
+ rsr a4, EXCSAVE_1 /* restore original a0 (now in a4) */
+ slli a3, a3, PS_OWB_SHIFT
+ xor a2, a2, a3 /* flip changed bits in old window base */
+ wsr a2, PS /* update PS.OWB to new window base */
+ rsync
+
+ _bbci.l a4, 31, _WindowUnderflow4
+ rotw -1 /* original a0 goes to a8 */
+ _bbci.l a8, 30, _WindowUnderflow8
+ rotw -1
+ j _WindowUnderflow12
+
+/*
+--------------------------------------------------------------------------------
+Window Overflow Exception for Call8
+
+Invoked if a call[i] referenced a register (a4-a15)
+that contains data from ancestor call[j];
+call[j] had done a call8 to call[j+1].
+On entry here:
+ window rotated to call[j] start point;
+ a0-a7 are registers to be saved;
+ a8-a15 must be preserved;
+ a9 is call[j+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0x80
+ .global _WindowOverflow8
+_WindowOverflow8:
+
+ s32e a0, a9, -16 /* save a0 to call[j+1]'s stack frame */
+ l32e a0, a1, -12 /* a0 <- call[j-1]'s sp
+ (used to find end of call[j]'s frame) */
+ s32e a1, a9, -12 /* save a1 to call[j+1]'s stack frame */
+ s32e a2, a9, -8 /* save a2 to call[j+1]'s stack frame */
+ s32e a3, a9, -4 /* save a3 to call[j+1]'s stack frame */
+ s32e a4, a0, -32 /* save a4 to call[j]'s stack frame */
+ s32e a5, a0, -28 /* save a5 to call[j]'s stack frame */
+ s32e a6, a0, -24 /* save a6 to call[j]'s stack frame */
+ s32e a7, a0, -20 /* save a7 to call[j]'s stack frame */
+ rfwo /* rotates back to call[i] position */
+
+/*
+--------------------------------------------------------------------------------
+Window Underflow Exception for Call8
+
+Invoked by RETW returning from call[i+1] to call[i]
+where call[i]'s registers must be reloaded (not live in ARs);
+where call[i] had done a call8 to call[i+1].
+On entry here:
+ window rotated to call[i] start point;
+ a0-a7 are undefined, must be reloaded with call[i].reg[0..7];
+ a8-a15 must be preserved (they are call[i+1].reg[0..7]);
+ a9 is call[i+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0xC0
+ .global _WindowUnderflow8
+_WindowUnderflow8:
+
+ l32e a0, a9, -16 /* restore a0 from call[i+1]'s stack frame */
+ l32e a1, a9, -12 /* restore a1 from call[i+1]'s stack frame */
+ l32e a2, a9, -8 /* restore a2 from call[i+1]'s stack frame */
+ l32e a7, a1, -12 /* a7 <- call[i-1]'s sp
+ (used to find end of call[i]'s frame) */
+ l32e a3, a9, -4 /* restore a3 from call[i+1]'s stack frame */
+ l32e a4, a7, -32 /* restore a4 from call[i]'s stack frame */
+ l32e a5, a7, -28 /* restore a5 from call[i]'s stack frame */
+ l32e a6, a7, -24 /* restore a6 from call[i]'s stack frame */
+ l32e a7, a7, -20 /* restore a7 from call[i]'s stack frame */
+ rfwu
+
+/*
+--------------------------------------------------------------------------------
+Window Overflow Exception for Call12
+
+Invoked if a call[i] referenced a register (a4-a15)
+that contains data from ancestor call[j];
+call[j] had done a call12 to call[j+1].
+On entry here:
+ window rotated to call[j] start point;
+ a0-a11 are registers to be saved;
+ a12-a15 must be preserved;
+ a13 is call[j+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0x100
+ .global _WindowOverflow12
+_WindowOverflow12:
+
+ s32e a0, a13, -16 /* save a0 to call[j+1]'s stack frame */
+ l32e a0, a1, -12 /* a0 <- call[j-1]'s sp
+ (used to find end of call[j]'s frame) */
+ s32e a1, a13, -12 /* save a1 to call[j+1]'s stack frame */
+ s32e a2, a13, -8 /* save a2 to call[j+1]'s stack frame */
+ s32e a3, a13, -4 /* save a3 to call[j+1]'s stack frame */
+ s32e a4, a0, -48 /* save a4 to end of call[j]'s stack frame */
+ s32e a5, a0, -44 /* save a5 to end of call[j]'s stack frame */
+ s32e a6, a0, -40 /* save a6 to end of call[j]'s stack frame */
+ s32e a7, a0, -36 /* save a7 to end of call[j]'s stack frame */
+ s32e a8, a0, -32 /* save a8 to end of call[j]'s stack frame */
+ s32e a9, a0, -28 /* save a9 to end of call[j]'s stack frame */
+ s32e a10, a0, -24 /* save a10 to end of call[j]'s stack frame */
+ s32e a11, a0, -20 /* save a11 to end of call[j]'s stack frame */
+ rfwo /* rotates back to call[i] position */
+
+/*
+--------------------------------------------------------------------------------
+Window Underflow Exception for Call12
+
+Invoked by RETW returning from call[i+1] to call[i]
+where call[i]'s registers must be reloaded (not live in ARs);
+where call[i] had done a call12 to call[i+1].
+On entry here:
+ window rotated to call[i] start point;
+ a0-a11 are undefined, must be reloaded with call[i].reg[0..11];
+ a12-a15 must be preserved (they are call[i+1].reg[0..3]);
+ a13 is call[i+1]'s stack pointer.
+--------------------------------------------------------------------------------
+*/
+
+ .org 0x140
+ .global _WindowUnderflow12
+_WindowUnderflow12:
+
+ l32e a0, a13, -16 /* restore a0 from call[i+1]'s stack frame */
+ l32e a1, a13, -12 /* restore a1 from call[i+1]'s stack frame */
+ l32e a2, a13, -8 /* restore a2 from call[i+1]'s stack frame */
+ l32e a11, a1, -12 /* a11 <- call[i-1]'s sp
+ (used to find end of call[i]'s frame) */
+ l32e a3, a13, -4 /* restore a3 from call[i+1]'s stack frame */
+ l32e a4, a11, -48 /* restore a4 from end of call[i]'s stack frame */
+ l32e a5, a11, -44 /* restore a5 from end of call[i]'s stack frame */
+ l32e a6, a11, -40 /* restore a6 from end of call[i]'s stack frame */
+ l32e a7, a11, -36 /* restore a7 from end of call[i]'s stack frame */
+ l32e a8, a11, -32 /* restore a8 from end of call[i]'s stack frame */
+ l32e a9, a11, -28 /* restore a9 from end of call[i]'s stack frame */
+ l32e a10, a11, -24 /* restore a10 from end of call[i]'s stack frame */
+ l32e a11, a11, -20 /* restore a11 from end of call[i]'s stack frame */
+ rfwu
+
+#endif /* XCHAL_HAVE_WINDOWED */
+
+#endif /* XCHAL_HAVE_XEA2 */
+
diff --git a/ports/xtensa/xcc/src/xtensa_vectors_xea3.S b/ports/xtensa/xcc/src/xtensa_vectors_xea3.S
new file mode 100644
index 00000000..5596a75c
--- /dev/null
+++ b/ports/xtensa/xcc/src/xtensa_vectors_xea3.S
@@ -0,0 +1,392 @@
+/**************************************************************************/
+/* Copyright (c) Cadence Design Systems, Inc. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* DESCRIPTION */
+/* */
+/* Xtensa exception and interrupt dispatch for XEA3. */
+/* */
+/* Interrupt handlers and user exception handlers support interaction */
+/* with the RTOS by calling XT_RTOS_INT_ENTER and XT_RTOS_INT_EXIT */
+/* before and after calling the user's specific interrupt handlers. */
+/* */
+/* Users can install application-specific interrupt handlers by calling */
+/* xt_set_interrupt_handler(). These handlers can be written in C and */
+/* must follow the C calling convention. The handler table is indexed by */
+/* the interrupt number. Each handler may be provided with an argument. */
+/* */
+/* Users can install application-specific exception handlers in the */
+/* same way, by calling xt_set_exception_handler(). One handler slot is */
+/* provided for each exception type. Note that some exceptions are */
+/* handled by the porting layer itself, and cannot be taken over by */
+/* application code. These are the alloca, syscall, and coprocessor */
+/* exceptions. */
+/* */
+/* Exception handlers can be written in C, and must follow C calling */
+/* convention. Each handler is passed a pointer to an exception frame as */
+/* its single argument. The exception frame is created on the stack and */
+/* holds the saved context of the thread that took the exception. If the */
+/* handler returns, the context will be restored and the instruction */
+/* that caused the exception will be retried. If the handler makes any */
+/* changes to the saved state in the exception frame, the changes will */
+/* be applied when restoring the context. */
+/* */
+/* RELEASE HISTORY */
+/* */
+/* DATE NAME DESCRIPTION */
+/* */
+/* 12-31-2020 Cadence Design Systems Initial Version 6.1.3 */
+/* */
+/**************************************************************************/
+
+
+#include
+#include
+
+#if XCHAL_HAVE_XEA3
+
+#include "xtensa_context.h"
+
+#if (XCHAL_HW_VERSION < XTENSA_HWVERSION_RH_2016_2)
+#error Xtensa HW earlier than RH_2016.2 not supported.
+#endif
+
+
+//-----------------------------------------------------------------------------
+// The entry point vectors are common for call0 and windowed configurations.
+//-----------------------------------------------------------------------------
+
+ .extern _DoubleExceptionHandler
+ .extern _xtos_exc_dispatch
+
+ .section .DispatchVector.text, "ax"
+#if XCHAL_HAVE_VECBASE
+ .align 64 // 64-byte alignment needed when vecbase
+#else // is relocatable
+ .align 4
+#endif
+
+ .org 0 // Fixed offset for Reset Vector
+ .global _DispatchVector
+ .weak _DispatchVector
+
+_DispatchVector:
+ j _JumpToResetHandler
+
+ .org 3 // Reserved
+ .local _Reserved1
+
+_Reserved1:
+ ill
+
+ .org 6 // Fixed offset for Double Exception Vector
+ .global _DoubleExceptionVector
+ .weak _DoubleExceptionVector
+
+_DoubleExceptionVector:
+ j _DoubleExceptionHandler
+
+ .org 9 // Reserved
+ .local _Reserved2
+
+_Reserved2:
+ ill
+
+//-----------------------------------------------------------------------------
+// Start of dispatch code.
+//-----------------------------------------------------------------------------
+
+ .org 12 // Fixed offset for Tailchain entry point
+ .global _xt_dispatch
+
+_xt_dispatch:
+#ifdef __XTENSA_CALL0_ABI__
+
+ // NOTE: for call0, a15 is expected to be holding the previous stack pointer
+ // when we get to the Tailchain segment.
+
+ s32si.x4 a2, a15 // Select interrupt, a2 <- (intnum << 2)
+ movi a0, 0
+ l32dis.it a0, a0 // a0 <- wrapper addr (handler_table[0])
+ s32stk a9, a15, 96 // Set new stack pointer
+#if XT_STK_XTRA_SZ
+ addi a1, a1, -XT_STK_XTRA_SZ // Adjust for extra save area
+#endif
+ s32dis.h a0, a0 // Jump to handler if interrupt else fall through
+ // Note this also clears local exclusive monitor
+
+#else // windowed
+
+ s32si.x4 a10, a1 // Select interrupt, a10 <- (intnum << 2)
+ movi a8, 0
+ l32dis.it a8, a8 // a8 <- wrapper addr (handler_table[0])
+ s32stk a9, a1, 96 // Set new stack pointer
+#if XT_STK_XTRA_SZ
+ addi a9, a9, -XT_STK_XTRA_SZ // Adjust for extra save area
+#endif
+ s32dis.h a8, a8 // Jump to handler if interrupt else fall through
+ // Note this also clears local exclusive monitor
+
+#endif // __XTENSA_CALL0_ABI__
+
+.Lexit:
+ j _xt_exit
+
+#ifndef __XTENSA_CALL0_ABI__
+ .org 36 // Fixed offset for Underflow segment
+ .global _xt_underflow
+
+_xt_underflow:
+ l32e a8, a1, -64 // a8 <- [a1-32]
+ l32e a9, a1, -64 // a9 <- [a1-28]
+ l32e a10, a1, -64 // a10 <- [a1-24]
+ l32e a11, a1, -64 // a11 <- [a1-20]
+ l32e a12, a1, -64 // a12 <- [a1-16]
+ l32e a13, a1, -64 // a13 <- [a1-12]
+ l32e a14, a1, -64 // a14 <- [a1-8]
+ l32e a15, a1, -64 // a15 <- [a1-4] ; Return (branch to EPC)
+#endif
+
+ .org 60 // Fixed offset for Save/Overflow segment
+ .global _xt_save
+
+_xt_save:
+#ifdef __XTENSA_CALL0_ABI__
+ s32e a0, a1, -64 // [a1-64] <- a0
+ s32e a2, a1, -48 // [a1-56] <- a2 ; a2 <- EPC
+ s32e a3, a1, -64 // [a1-52] <- a3
+ s32e a4, a1, -64 // [a1-48] <- a4
+ s32e a5, a1, -64 // [a1-44] <- a5
+ s32e a6, a1, -64 // [a1-40] <- a6
+ s32e a7, a1, -64 // [a1-36] <- a7
+#else
+ .global _xt_overflow
+_xt_overflow:
+#endif
+ s32e a8, a1, -52 // [a1-32] <- a8 ; a8 <- ExcVAddr
+ s32e a9, a1, -28 // [a1-28] <- a9 ; a9 <- PS/SAR
+ s32e a10, a1, -48 // [a1-24] <- a10 ; a10 <- EPC
+ s32e a11, a1, -24 // [a1-20] <- a11 ; a11 <- ExcCause
+ s32e a12, a1, -44 // [a1-16] <- a12 ; a12 <- LBEG
+ s32e a13, a1, -40 // [a1-12] <- a13 ; a13 <- LEND
+ s32e a14, a1, -36 // [a1-8] <- a14 ; a14 <- LCOUNT
+ s32e a15, a1, -32 // [a1-4] <- a15 ; a15 <- a1
+ // If Overflow then return (branch to EPC)
+
+_xt_entry:
+ s32e a8, a1, -4 // [a1-68] <- a8 (ExcVAddr)
+ s32e a11, a1, -8 // [a1-72] <- a11 (ExcCause)
+#if XCHAL_HAVE_LOOPS
+ s32e a12, a1, -20 // [a1-84] <- a12 (LBEG)
+ s32e a13, a1, -24 // [a1-88] <- a13 (LEND)
+ s32e a14, a1, -28 // [a1-92] <- a14 (LCOUNT)
+#endif
+#if XCHAL_HAVE_EXCLUSIVE
+ movi a12, 0
+ getex a12
+ s32e a12, a1, -32 // [a1-96] <- a12 (ATOMCTL)
+#endif
+
+ j 1f // make room for literals
+
+ .align 4
+ .literal_position
+
+.Le1:
+ .word _xt_exception_table
+
+1:
+ // Call OS-specific code for additional work to be done. Stay on interruptee's
+ // stack in case more saves are required into stack frame.
+ // NOTE: OS-specific code can use a8, a12-a14, (+a2-a7: call0, a15: windowed).
+ // ALL other registers must be preserved.
+
+ XT_RTOS_INT_ENTER
+
+ // This sequence checks the interrupt controller and loads the interrupt
+ // number if available, and also loads the wrapper handler address.
+ // If there is an interrupt, execution will branch to the wrapper which
+ // will then forward to the correct handler.
+ // All this happens only if there is a pending interrupt. If not, execution
+ // falls through to exception handling.
+
+#ifdef __XTENSA_CALL0_ABI__
+
+ s32si.x4 a2, a1 // [a1-80] <- a2 (EPC) ; a2 <- (intnum << 2)
+ movi a0, 0
+ l32dis.it a0, a0 // a0 <- wrapper addr (handler_table[0])
+ s32stk a9, a1, 96 // [a1-76] <- a9 (PS/SAR) ; a1 = a1-96
+#if XT_STK_XTRA_SZ
+ addi a1, a1, -XT_STK_XTRA_SZ // Adjust for extra save area
+#endif
+ s32dis.h a0, a0 // Jump to handler if interrupt else fall through
+
+#else // windowed
+
+ s32si.x4 a10, a1 // [a1-80] <- a10 (EPC) ; a10 <- (intnum << 2)
+ movi a8, 0
+ l32dis.it a8, a8 // a8 <- wrapper addr (handler_table[0])
+ s32stk a9, a1, 96 // [a1-76] <- a9 (PS/SAR) ; a9 = a1-96
+#if XT_STK_XTRA_SZ
+ addi a9, a9, -XT_STK_XTRA_SZ // Adjust for extra save area
+#endif
+ s32dis.h a8, a8 // Jump to handler if interrupt else fall through
+
+#endif // __XTENSA_CALL0_ABI__
+
+ // At this point we have:
+ // (note window has rotated for windowed ABI)
+ // a0 holds return address (Tailchain+3)
+ // For call0:
+ // a11 holds ExcCause, also saved in [oldsp - 72]
+ // a15 holds exception SP, a1 points to exception frame
+ // For windowed:
+ // a3 holds ExcCause, also saved in [oldsp - 72]
+ // a1 points to exception frame
+
+ .global _xt_exception
+
+_xt_exception:
+ l32r a2, .Le1 // Load exc table address
+#ifdef __XTENSA_CALL0_ABI__
+ mov a3, a11 // Copy exception cause to a3
+#endif
+ extui a4, a3, 0, 4 // Extract exception cause
+ addx4 a2, a4, a2 // Index into exc table
+ l32i a4, a2, 0 // Load handler address
+#if XT_STK_XTRA_SZ
+ addi a2, a1, XT_STK_XTRA_SZ // Argument = Exception frame ptr
+#else
+ mov a2, a1 // Argument = Exception frame ptr
+#endif
+ jx a4 // Return directly from handler
+
+ // Exit/restore sequence
+
+ .global _xt_exit
+
+_xt_exit:
+#ifdef __XTENSA_CALL0_ABI__
+ mov a1, a15 // Restore stack pointer
+#endif
+
+ // Run OS-specific code to determine what to restore.
+ // Interrupts will remain disabled through this sequence.
+ // WARNING: stack pointer may change within this macro
+ // so all restores off the stack must happen afterwards.
+
+ XT_RTOS_INT_EXIT
+
+ .global _xt_restore
+
+_xt_restore:
+ // Some loads must happen before DISPST = Restore, as these
+ // will not be accessible via L32E once DISPST = Restore.
+
+#if XCHAL_HAVE_EXCLUSIVE
+ l32e a12, a1, -32 // a12 <- [a1-96] (ATOMCTL)
+ getex a12
+#endif
+ l32e a10, a1, -12 // a10 <- [a1-76] (PS/SAR)
+ l32e a12, a1, -20 // a12 <- [a1-84] (LBEG)
+ l32e a13, a1, -24 // a13 <- [a1-88] (LEND)
+ l32e a14, a1, -28 // a14 <- [a1-92] (LCOUNT)
+ l32dis.epc a11, a1 // a11 <- [a1-80] (EPC)
+ // If interrupt goto tailchain else fall through
+
+#ifdef __XTENSA_CALL0_ABI__
+ l32e a0, a1, -64 // a0 <- [a1-64]
+ l32e a2, a1, -64 // a2 <- [a1-56]
+ l32e a3, a1, -64 // a3 <- [a1-52]
+ l32e a4, a1, -64 // a4 <- [a1-48]
+ l32e a5, a1, -64 // a5 <- [a1-44]
+ l32e a6, a1, -64 // a6 <- [a1-40]
+ l32e a7, a1, -64 // a7 <- [a1-36]
+#endif
+
+ // Important: the following restrictions must be observed:
+ // 1) The LCOUNT register must be restored after LBEG/LEND.
+ // 2) There must be at least 3 instructions between the LCOUNT
+ // restore and the last L32E (the one that branches).
+
+ l32e a12, a1, -44 // LBEG <- a12, a12 <- [a1-16]
+ l32e a13, a1, -40 // LEND <- a13, a13 <- [a1-12]
+ l32e a14, a1, -36 // LCOUNT <- a14, a14 <- [a1-8]
+ l32e a8, a1, -64 // a8 <- [a1-32]
+ l32e a9, a1, -64 // a9 <- [a1-28]
+ l32e a10, a1, -60 // PS/SAR <- a10, a10 <- [a1-24]
+ l32e a11, a1, -48 // EPC <- a11, a11 <- [a1-20]
+ l32e a15, a1, -64 // a15 <- [a1-4], Branch to EPC if no interrupt
+ // If interrupt, branch to Tailchain
+
+
+//-----------------------------------------------------------------------------
+// Branch to reset handler code from here. Use CALL0 as a branch, will expand
+// to CALLX0 if needed when built with the -mlongcalls option.
+//-----------------------------------------------------------------------------
+
+ .align 4
+ .local _JumpToResetHandler
+
+_JumpToResetHandler:
+ call0 _ResetHandler
+
+
+//-----------------------------------------------------------------------------
+// Idle loop. On interrupt, no state needs saving.
+//-----------------------------------------------------------------------------
+
+ .align 4
+ .global _xt_idle
+
+_xt_idle:
+ movi a14, _xt_interrupt_stack_top
+ mov a1, a14 // a1 <- Top of interrupt stack
+ movi a14, 0 // 0 = Normal
+ wsr.ms a14 // Set DISPST = Normal
+ rsync
+ waiti 0 // Wait for interrupt
+ memw // HW erratum 569
+
+
+//-----------------------------------------------------------------------------
+// Scheduler interrupt handler. Triggered by context switch. At this time only
+// useful for windowed ABI to spill register windows.
+//-----------------------------------------------------------------------------
+
+ .align 4
+ .global xt_sched_handler
+
+xt_sched_handler:
+#ifdef __XTENSA_WINDOWED_ABI__
+ entry a1, 32
+ ssai 1
+ spillw
+ retw
+#else
+ ret
+#endif
+
+#endif // XCHAL_HAVE_XEA3
+
diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx.bat b/ports_module/cortex-m7/ac5/example_build/build_threadx.bat
index caa281e3..c355a2f9 100644
--- a/ports_module/cortex-m7/ac5/example_build/build_threadx.bat
+++ b/ports_module/cortex-m7/ac5/example_build/build_threadx.bat
@@ -1,5 +1,7 @@
del tx.a
+
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork tx_initialize_low_level.S
+
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_thread_stack_build.S
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_thread_schedule.S
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_thread_system_return.S
@@ -9,6 +11,16 @@ armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/s
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_timer_interrupt.S
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_disable.S
armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/tx_thread_interrupt_restore.S
+
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_alignment_adjust.c
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_external_memory_enable.c
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_memory_fault_handler.c
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_memory_fault_notify.c
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_mm_register_setup.c
+
+armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/txm_module_manager_thread_stack_build.S
+armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/txm_module_manager_user_mode_entry.S
+
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_allocate.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_cleanup.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_block_pool_create.c
@@ -133,6 +145,7 @@ armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../..
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_buffer_full_notify.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_filter.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/tx_trace_event_unfilter.c
+
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_allocate.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_create.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_block_pool_delete.c
@@ -193,6 +206,8 @@ armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../..
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_deactivate.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_delete.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common/inc ../../../../common/src/txe_timer_info_get.c
+
+armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_absolute_load.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_application_request.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_callback_request.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_event_flags_notify_trampoline.c
@@ -219,17 +234,10 @@ armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_timer_notify_trampoline.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_unload.c
armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../../../../common_modules/module_manager/src/txm_module_manager_util.c
-armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_alignment_adjust.c
-armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_external_memory_enable.c
-armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_memory_fault_handler.c
-armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_memory_fault_notify.c
-armcc -g -O0 --cpu=cortex-m7.fp.dp -c -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc ../module_manager/src/txm_module_manager_mm_register_setup.c
-armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/txm_module_manager_thread_stack_build.S
-armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork ../module_manager/src/txm_module_manager_user_mode_entry.S
armar --create tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o tx_initialize_low_level.o tx_thread_interrupt_disable.o tx_thread_interrupt_restore.o tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o
armar -r tx.a tx_event_flags_performance_system_info_get.o tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o
armar -r tx.a tx_semaphore_put_notify.o tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
armar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o
armar -r tx.a txe_queue_prioritize.o txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o txm_module_manager_alignment_adjust.o txm_module_manager_application_request.o txm_module_manager_callback_request.o txm_module_manager_event_flags_notify_trampoline.o txm_module_manager_external_memory_enable.o txm_module_manager_file_load.o txm_module_manager_in_place_load.o
-armar -r tx.a txm_module_manager_initialize.o txm_module_manager_kernel_dispatch.o txm_module_manager_maximum_module_priority_set.o txm_module_manager_memory_fault_handler.o txm_module_manager_memory_fault_notify.o txm_module_manager_memory_load.o txm_module_manager_object_pointer_get.o txm_module_manager_object_pool_create.o txm_module_manager_queue_notify_trampoline.o txm_module_manager_semaphore_notify_trampoline.o txm_module_manager_mm_register_setup.o txm_module_manager_start.o txm_module_manager_stop.o txm_module_manager_thread_create.o txm_module_manager_thread_notify_trampoline.o txm_module_manager_thread_reset.o txm_module_manager_timer_notify_trampoline.o txm_module_manager_unload.o txm_module_manager_thread_stack_build.o txm_module_manager_internal_load.o txm_module_manager_object_allocate.o txm_module_manager_object_deallocate.o txm_module_manager_object_pointer_get_extended.o txm_module_manager_properties_get.o txm_module_manager_util.o txm_module_manager_user_mode_entry.o
+armar -r tx.a txm_module_manager_initialize.o txm_module_manager_kernel_dispatch.o txm_module_manager_maximum_module_priority_set.o txm_module_manager_memory_fault_handler.o txm_module_manager_memory_fault_notify.o txm_module_manager_memory_load.o txm_module_manager_object_pointer_get.o txm_module_manager_object_pool_create.o txm_module_manager_queue_notify_trampoline.o txm_module_manager_semaphore_notify_trampoline.o txm_module_manager_mm_register_setup.o txm_module_manager_start.o txm_module_manager_stop.o txm_module_manager_thread_create.o txm_module_manager_thread_notify_trampoline.o txm_module_manager_thread_reset.o txm_module_manager_timer_notify_trampoline.o txm_module_manager_unload.o txm_module_manager_thread_stack_build.o txm_module_manager_internal_load.o txm_module_manager_object_allocate.o txm_module_manager_object_deallocate.o txm_module_manager_object_pointer_get_extended.o txm_module_manager_properties_get.o txm_module_manager_util.o txm_module_manager_user_mode_entry.o txm_module_manager_absolute_load.o
diff --git a/ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat b/ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat
index da979bd9..ed8a78ef 100644
--- a/ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat
+++ b/ports_module/cortex-m7/ac5/example_build/build_threadx_demo.bat
@@ -1,4 +1,4 @@
-armasm -g --cpu=cortex-m7.fp.dp --apcs=/interwork tx_initialize_low_level.S
+armasm -g --cpreproc --cpu=cortex-m7.fp.dp --apcs=/interwork tx_initialize_low_level.S
armcc -c -g --cpu=cortex-m7.fp.dp -O2 -I../inc -I../../../../common_modules/inc -I../../../../common_modules/module_manager/inc -I../../../../common/inc sample_threadx.c
armlink -d -o sample_threadx.axf --elf --map --ro-base=0x00000000 --rw-base=0x20000000 --first __tx_vectors --datacompressor=off --inline --info=inline --callgraph --list sample_threadx.map tx_initialize_low_level.o sample_threadx.o tx.a
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject b/ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject
index 9d81f0c7..fc1cb75e 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx/.cproject
@@ -55,8 +55,6 @@
-
+
@@ -133,23 +127,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx/.project b/ports_module/cortex-m7/ac6/example_build/sample_threadx/.project
index 2a6b3cb1..725328bd 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx/.project
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx/.project
@@ -3,7 +3,6 @@
sample_threadx
- tx
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject
index ccfc3584..1e1ea739 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.cproject
@@ -57,10 +57,6 @@
-
+
@@ -185,29 +175,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.project b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.project
index 5f1f1fa6..17f6aba3 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.project
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module/.project
@@ -3,7 +3,6 @@
sample_threadx_module
- txm
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject
index 0cf83cff..f6ca2712 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.cproject
@@ -55,8 +55,6 @@
-
+
@@ -135,25 +129,7 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.project b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.project
index bddfb9ee..f1ca14fa 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.project
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/.project
@@ -3,8 +3,6 @@
sample_threadx_module_manager
- sample_threadx_module
- tx
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds
deleted file mode 100644
index b1993316..00000000
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.ds
+++ /dev/null
@@ -1,3 +0,0 @@
-wait
-load ..\sample_threadx_module\Debug\sample_threadx_module.axf
-wait
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch
index d088487d..6cace9e2 100644
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch
+++ b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager.launch
@@ -1,57 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
+
-
+
-
-
+
+
-
+
-
+
-
+
-
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
@@ -73,11 +85,11 @@
-
+
-
+
@@ -87,11 +99,11 @@
-
+
-
+
@@ -125,8 +137,9 @@
-
-
+
+
+
@@ -136,14 +149,15 @@
+
+
-
-
+
@@ -165,8 +179,8 @@
-
-
+
+
@@ -192,7 +206,7 @@
-
+
@@ -216,8 +230,6 @@
-
-
diff --git a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds b/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds
deleted file mode 100644
index fc83a4f2..00000000
--- a/ports_module/cortex-m7/ac6/example_build/sample_threadx_module_manager/sample_threadx_module_manager_debug.ds
+++ /dev/null
@@ -1,3 +0,0 @@
-wait
-add-symbol-file ..\sample_threadx_module\Debug\sample_threadx_module.axf
-wait
diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx.bat b/ports_module/cortex-m7/gnu/example_build/build_threadx.bat
index b45a175f..4250db1e 100644
--- a/ports_module/cortex-m7/gnu/example_build/build_threadx.bat
+++ b/ports_module/cortex-m7/gnu/example_build/build_threadx.bat
@@ -1,5 +1,7 @@
del tx.a
+
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb tx_initialize_low_level.S
+
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb ..\module_manager\src\tx_thread_stack_build.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb ..\module_manager\src\tx_thread_schedule.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb ..\module_manager\src\tx_thread_system_return.S
@@ -9,6 +11,12 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb ..\module_manager\src\tx_timer_interrupt.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb ..\module_manager\src\txm_module_manager_thread_stack_build.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_alignment_adjust.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_external_memory_enable.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_memory_fault_handler.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_mm_register_setup.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_memory_fault_notify.c
+
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc ..\..\..\..\common\src\tx_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc ..\..\..\..\common\src\tx_block_pool_cleanup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc ..\..\..\..\common\src\tx_block_pool_create.c
@@ -194,19 +202,16 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc ..\..\..\..\common\src\txe_timer_delete.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc ..\..\..\..\common\src\txe_timer_info_get.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_alignment_adjust.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_absolute_load.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_application_request.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_callback_request.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_event_flags_notify_trampoline.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_external_memory_enable.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_file_load.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_in_place_load.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_internal_load.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_initialize.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_kernel_dispatch.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_maximum_module_priority_set.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_memory_fault_handler.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_memory_fault_notify.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_memory_load.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_object_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_object_deallocate.c
@@ -216,7 +221,6 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_properties_get.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_queue_notify_trampoline.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_semaphore_notify_trampoline.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\module_manager\src\txm_module_manager_mm_register_setup.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_start.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_stop.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc -I..\..\..\..\common_modules\module_manager\inc ..\..\..\..\common_modules\module_manager\src\txm_module_manager_thread_create.c
@@ -252,6 +256,7 @@ arm-none-eabi-ar -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_perf
arm-none-eabi-ar -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
arm-none-eabi-ar -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
arm-none-eabi-ar -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+
arm-none-eabi-ar -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
arm-none-eabi-ar -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
arm-none-eabi-ar -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
@@ -265,16 +270,11 @@ arm-none-eabi-ar -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_
arm-none-eabi-ar -r tx.a txm_module_manager_alignment_adjust.o txm_module_manager_application_request.o txm_module_manager_callback_request.o
arm-none-eabi-ar -r tx.a txm_module_manager_event_flags_notify_trampoline.o txm_module_manager_external_memory_enable.o txm_module_manager_file_load.o
-arm-none-eabi-ar -r tx.a txm_module_manager_in_place_load.o txm_module_manager_initialize.o
+arm-none-eabi-ar -r tx.a txm_module_manager_absolute_load.o txm_module_manager_in_place_load.o txm_module_manager_initialize.o txm_module_manager_internal_load.o
arm-none-eabi-ar -r tx.a txm_module_manager_kernel_dispatch.o txm_module_manager_maximum_module_priority_set.o txm_module_manager_memory_fault_handler.o
arm-none-eabi-ar -r tx.a txm_module_manager_memory_fault_notify.o txm_module_manager_memory_load.o txm_module_manager_object_pointer_get.o
arm-none-eabi-ar -r tx.a txm_module_manager_object_pool_create.o txm_module_manager_queue_notify_trampoline.o txm_module_manager_semaphore_notify_trampoline.o
arm-none-eabi-ar -r tx.a txm_module_manager_mm_register_setup.o txm_module_manager_start.o txm_module_manager_stop.o
arm-none-eabi-ar -r tx.a txm_module_manager_thread_create.o txm_module_manager_thread_notify_trampoline.o txm_module_manager_thread_reset.o
arm-none-eabi-ar -r tx.a txm_module_manager_timer_notify_trampoline.o txm_module_manager_unload.o txm_module_manager_thread_stack_build.o
-arm-none-eabi-ar -r tx.a txm_module_manager_internal_load.o
-arm-none-eabi-ar -r tx.a txm_module_manager_object_allocate.o
-arm-none-eabi-ar -r tx.a txm_module_manager_object_deallocate.o
-arm-none-eabi-ar -r tx.a txm_module_manager_object_pointer_get_extended.o
-arm-none-eabi-ar -r tx.a txm_module_manager_properties_get.o
-arm-none-eabi-ar -r tx.a txm_module_manager_util.o
\ No newline at end of file
+arm-none-eabi-ar -r tx.a txm_module_manager_object_allocate.o txm_module_manager_object_deallocate.o txm_module_manager_object_pointer_get_extended.o txm_module_manager_properties_get.o txm_module_manager_util.o
\ No newline at end of file
diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat b/ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat
index 1b8f6a06..a6660a86 100644
--- a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat
+++ b/ports_module/cortex-m7/gnu/example_build/build_threadx_module_library.bat
@@ -1,5 +1,7 @@
del txm.a
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\module_lib\src\txm_module_thread_shell_entry.c
+
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_block_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_block_pool_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_block_pool_delete.c
@@ -29,7 +31,6 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_module_object_allocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_module_object_deallocate.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_module_object_pointer_get.c
-arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\module_lib\src\txm_module_thread_shell_entry.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_module_thread_system_suspend.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_mutex_create.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_mutex_delete.c
@@ -98,21 +99,6 @@ arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_trace_isr_exit_insert.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -fpic -fno-plt -mpic-data-is-text-relative -msingle-pic-base -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc ..\..\..\..\common_modules\module_lib\src\txm_trace_user_event_insert.c
-arm-none-eabi-ar -r txm.a txm_block_allocate.o txm_block_pool_create.o txm_block_pool_delete.o txm_block_pool_info_get.o txm_block_pool_performance_info_get.o txm_block_pool_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_block_pool_prioritize.o txm_block_release.o
-arm-none-eabi-ar -r txm.a txm_byte_allocate.o txm_byte_pool_create.o txm_byte_pool_delete.o txm_byte_pool_info_get.o txm_byte_pool_performance_info_get.o txm_byte_pool_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_byte_pool_prioritize.o txm_byte_release.o
-arm-none-eabi-ar -r txm.a txm_event_flags_create.o txm_event_flags_delete.o txm_event_flags_get.o txm_event_flags_info_get.o txm_event_flags_performance_info_get.o txm_event_flags_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_event_flags_set.o txm_event_flags_set_notify.o
-arm-none-eabi-ar -r txm.a txm_module_application_request.o txm_module_callback_request_thread_entry.o txm_module_object_allocate.o txm_module_object_deallocate.o txm_module_object_pointer_get.o txm_module_thread_shell_entry.o txm_module_thread_system_suspend.o
-arm-none-eabi-ar -r txm.a txm_mutex_create.o txm_mutex_delete.o txm_mutex_get.o txm_mutex_info_get.o txm_mutex_performance_info_get.o txm_mutex_performance_system_info_get.o txm_mutex_prioritize.o txm_mutex_put.o
-arm-none-eabi-ar -r txm.a txm_queue_create.o txm_queue_delete.o txm_queue_flush.o txm_queue_front_send.o txm_queue_info_get.o txm_queue_performance_info_get.o txm_queue_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_queue_prioritize.o txm_queue_receive.o txm_queue_send.o txm_queue_send_notify.o
-arm-none-eabi-ar -r txm.a txm_semaphore_ceiling_put.o txm_semaphore_create.o txm_semaphore_delete.o txm_semaphore_get.o txm_semaphore_info_get.o txm_semaphore_performance_info_get.o txm_semaphore_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_semaphore_prioritize.o txm_semaphore_put.o txm_semaphore_put_notify.o
-arm-none-eabi-ar -r txm.a txm_thread_create.o txm_thread_delete.o txm_thread_entry_exit_notify.o txm_thread_identify.o txm_thread_info_get.o txm_thread_interrupt_control.o txm_thread_performance_info_get.o
-arm-none-eabi-ar -r txm.a txm_thread_performance_system_info_get.o txm_thread_preemption_change.o txm_thread_priority_change.o txm_thread_relinquish.o txm_thread_reset.o txm_thread_resume.o
-arm-none-eabi-ar -r txm.a txm_thread_sleep.o txm_thread_stack_error_notify.o txm_thread_suspend.o txm_thread_terminate.o txm_thread_time_slice_change.o txm_thread_wait_abort.o
-arm-none-eabi-ar -r txm.a txm_time_get.o txm_time_set.o
-arm-none-eabi-ar -r txm.a txm_timer_activate.o txm_timer_change.o txm_timer_create.o txm_timer_deactivate.o txm_timer_delete.o txm_timer_info_get.o txm_timer_performance_info_get.o txm_timer_performance_system_info_get.o
-arm-none-eabi-ar -r txm.a txm_trace_buffer_full_notify.o txm_trace_disable.o txm_trace_enable.o txm_trace_event_filter.o txm_trace_event_unfilter.o txm_trace_isr_enter_insert.o txm_trace_isr_exit_insert.o txm_trace_user_event_insert.o
+arm-none-eabi-ar -r txm.a txm_block_allocate.o txm_block_pool_create.o txm_block_pool_delete.o txm_block_pool_info_get.o txm_block_pool_performance_info_get.o txm_block_pool_performance_system_info_get.o txm_block_pool_prioritize.o txm_block_release.o txm_byte_allocate.o txm_byte_pool_create.o txm_byte_pool_delete.o txm_byte_pool_info_get.o txm_byte_pool_performance_info_get.o txm_byte_pool_performance_system_info_get.o txm_byte_pool_prioritize.o txm_byte_release.o txm_event_flags_create.o txm_event_flags_delete.o txm_event_flags_get.o txm_event_flags_info_get.o txm_event_flags_performance_info_get.o txm_event_flags_performance_system_info_get.o txm_event_flags_set.o txm_event_flags_set_notify.o txm_thread_create.o txm_thread_delete.o txm_thread_entry_exit_notify.o txm_thread_identify.o txm_thread_info_get.o txm_thread_interrupt_control.o txm_thread_performance_info_get.o txm_time_get.o txm_time_set.o
+arm-none-eabi-ar -r txm.a txm_module_application_request.o txm_module_callback_request_thread_entry.o txm_module_object_allocate.o txm_module_object_deallocate.o txm_module_object_pointer_get.o txm_module_thread_shell_entry.o txm_module_thread_system_suspend.o txm_mutex_create.o txm_mutex_delete.o txm_mutex_get.o txm_mutex_info_get.o txm_mutex_performance_info_get.o txm_mutex_performance_system_info_get.o txm_mutex_prioritize.o txm_mutex_put.o txm_queue_create.o txm_queue_delete.o txm_queue_flush.o txm_queue_front_send.o txm_queue_info_get.o txm_queue_performance_info_get.o txm_queue_performance_system_info_get.o txm_queue_prioritize.o txm_queue_receive.o txm_queue_send.o txm_queue_send_notify.o txm_semaphore_ceiling_put.o txm_semaphore_create.o txm_semaphore_delete.o txm_semaphore_get.o txm_semaphore_info_get.o txm_semaphore_performance_info_get.o txm_semaphore_performance_system_info_get.o txm_semaphore_prioritize.o txm_semaphore_put.o txm_semaphore_put_notify.o
+arm-none-eabi-ar -r txm.a txm_thread_performance_system_info_get.o txm_thread_preemption_change.o txm_thread_priority_change.o txm_thread_relinquish.o txm_thread_reset.o txm_thread_resume.o txm_thread_sleep.o txm_thread_stack_error_notify.o txm_thread_suspend.o txm_thread_terminate.o txm_thread_time_slice_change.o txm_thread_wait_abort.o txm_timer_activate.o txm_timer_change.o txm_timer_create.o txm_timer_deactivate.o txm_timer_delete.o txm_timer_info_get.o txm_timer_performance_info_get.o txm_timer_performance_system_info_get.o txm_trace_buffer_full_notify.o txm_trace_disable.o txm_trace_enable.o txm_trace_event_filter.o txm_trace_event_unfilter.o txm_trace_isr_enter_insert.o txm_trace_isr_exit_insert.o txm_trace_user_event_insert.o
diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat b/ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat
index e361dfb2..244b7b73 100644
--- a/ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat
+++ b/ports_module/cortex-m7/gnu/example_build/build_threadx_module_manager_sample.bat
@@ -1,4 +1,4 @@
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc -I..\..\..\..\common_modules\inc sample_threadx_module_manager.c
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb tx_simulator_startup.S
arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb cortexm_crt0.S
-arm-none-eabi-ld -A cortex-m7 -ereset_handler -T sample_threadx.ld tx_simulator_startup.o cortexm_crt0.o sample_threadx_module_manager.o tx.a libc.a -o sample_threadx_module_manager.axf -M > sample_threadx_module_manager.map
+arm-none-eabi-gcc -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -nostartfiles -ereset_handler -T sample_threadx.ld tx_simulator_startup.o cortexm_crt0.o sample_threadx_module_manager.o tx.a -o sample_threadx_module_manager.axf -Wl,-Map=sample_threadx_module_manager.map
diff --git a/ports_module/cortex-m7/gnu/example_build/build_threadx_sample.bat b/ports_module/cortex-m7/gnu/example_build/build_threadx_sample.bat
new file mode 100644
index 00000000..5b008d0d
--- /dev/null
+++ b/ports_module/cortex-m7/gnu/example_build/build_threadx_sample.bat
@@ -0,0 +1,4 @@
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -I..\inc -I..\..\..\..\common\inc sample_threadx.c
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb tx_simulator_startup.S
+arm-none-eabi-gcc -c -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb cortexm_crt0.S
+arm-none-eabi-gcc -g -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-d16 -mthumb -nostartfiles -ereset_handler -T sample_threadx.ld tx_simulator_startup.o cortexm_crt0.o sample_threadx.o tx.a -lc -o sample_threadx.axf -Wl,-Map=sample_threadx.map
diff --git a/ports_module/cortex-m7/iar/example_build/tx.ewp b/ports_module/cortex-m7/iar/example_build/tx.ewp
index 0e44856f..7ff6209d 100644
--- a/ports_module/cortex-m7/iar/example_build/tx.ewp
+++ b/ports_module/cortex-m7/iar/example_build/tx.ewp
@@ -66,7 +66,7 @@