diff --git a/README.md b/README.md index 69dd035fa..e1026d816 100644 --- a/README.md +++ b/README.md @@ -1,117 +1,189 @@ -![cortex_m0](https://github.com/azure-rtos/threadx/workflows/cortex_m0/badge.svg) -![cortex_m3](https://github.com/azure-rtos/threadx/workflows/cortex_m3/badge.svg) -![cortex_m4](https://github.com/azure-rtos/threadx/workflows/cortex_m4/badge.svg) -![cortex_m7](https://github.com/azure-rtos/threadx/workflows/cortex_m7/badge.svg) - # Azure RTOS ThreadX This advanced real-time operating system (RTOS) is designed specifically for deeply embedded applications. Among the multiple benefits it provides are advanced scheduling facilities, message passing, interrupt management, and messaging services. Azure RTOS ThreadX has many advanced features, including picokernel architecture, preemption threshold, event chaining, and a rich set of system services. -## Documentation +Here are the key features and modules of ThreadX: -Documentation for this library can be found here: http://docs.microsoft.com/azure/rtos/threadx +![ThreadX Key Features](./docs/threadx-features.png) +## Getting Started -# Understanding inter-component dependencies +Azure RTOS has been integrated to the semiconductor's SDKs and development environment. You can develop using the tools of choice from [STMicroelectronics](https://www.st.com/content/st_com/en/campaigns/x-cube-azrtos-azure-rtos-stm32.html), [NXP](https://www.nxp.com/design/software/embedded-software/azure-rtos-for-nxp-microcontrollers:AZURE-RTOS), [Renesas](https://github.com/renesas/azure-rtos) and [Microchip](https://mu.microchip.com/get-started-simplifying-your-iot-design-with-azure-rtos). -The main components of Azure RTOS are each provided in their own repository, but there are dependencies between them--shown in the following graph--that are important to understand when setting up your builds. +We also provide [getting started guide](https://github.com/azure-rtos/getting-started) and [samples](https://github.com/azure-rtos/samples) using hero development boards from semiconductors you can build and test with. -![dependency graph](docs/deps.png) +See [Overview of Azure RTOS ThreadX](https://learn.microsoft.com/en-us/azure/rtos/threadx/overview-threadx) for the high-level overview, and all documentation and APIs can be found in: [Azure RTOS ThreadX documentation](https://learn.microsoft.com/en-us/azure/rtos/threadx/). -# Building and using the library +Also there is dedicated [learning path of Azure RTOS ThreadX](https://learn.microsoft.com/training/paths/azure-rtos-threadx/) for learning systematically. -## Prerequisites -Install the following tools: +## Repository Structure and Usage +### Directory layout -* [CMake](https://cmake.org/download/) version 3.0 or later -* [GCC compilers for arm-none-eabi](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) -* [Ninja](https://ninja-build.org/) + . + ├── cmake # CMakelist files for building the project + ├── common # Core ThreadX files + ├── common_modules # Core ThreadX module files + ├── common_smp # Core ThreadX SMP files + ├── docs # Documentation supplements + ├── ports # Architecture and compiler specific files. See below for directory breakdown + │ ├── cortex_m7 + │ │ ├── iar # Example IAR compiler sample project + │ │ │ ├── example build # IAR workspace and sample project files + │ │ │ ├── inc # tx_port.h for this architecture + │ │ │ └── src # Source files for this architecture + │ │ ├── ac6 # Example ac6/Keil sample project + │ │ ├── gnu # Example gnu sample project + │ │ └── ... + │ └── ... + ├── ports_modules # Architecture and compiler specific files for threadX modules + ├── ports_smp # Architecture and compiler specific files for threadX SMP + ├── samples # demo_threadx.c + └── utility # Test cases and utilities -## Cloning the repo -```bash -$ git clone https://github.com/azure-rtos/threadx.git -``` +## Branches & Releases -## Building as a static library +The master branch has the most recent code with all new features and bug fixes. It does not represent the latest General Availability (GA) release of the library. Each official release (preview or GA) will be tagged to mark the commit and push it into the Github releases tab, e.g. `v6.2-rel`. -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()`. +## Supported Architecture Ports -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. +### ThreadX +``` +arc_em cortex_a12 cortex_m0 cortex_r4 +arc_hs cortex_a15 cortex_m23 cortex_r5 +arm11 cortex_a17 cortex_m3 cortex_r7 +arm9 cortex_a34 cortex_m33 +c667x cortex_a35 cortex_m4 +linux cortex_a5 cortex_m55 +risc-v32 cortex_a53 cortex_m7 +rxv1 cortex_a55 cortex_m85 +rxv2 cortex_a57 +rxv3 cortex_a5x +win32 cortex_a65 +xtensa cortex_a65ae + cortex_a7 + cortex_a72 + cortex_a73 + cortex_a75 + cortex_a76 + cortex_a76ae + cortex_a77 + cortex_a8 + cortex_a9 +``` -```bash -$ cmake -Bbuild -DCMAKE_TOOLCHAIN_FILE=cmake/cortex_m4.cmake -GNinja . +### ThreadX Modules +[Azure RTOS ThreadX Modules](https://learn.microsoft.com/azure/rtos/threadx-modules/chapter1) component provides an infrastructure for applications to dynamically load modules that are built separately from the resident portion of the application. +``` +cortex_a35 +cortex_a35_smp +cortex_a7 +cortex_m0+ +cortex_m23 +cortex_m3 +cortex_m33 +cortex_m4 +cortex_m7 +cortex_r4 +rxv2 +``` -$ cmake --build ./build +### ThreadX SMP +[Azure RTOS ThreadX SMP](https://learn.microsoft.com/azure/rtos/threadx/threadx-smp/chapter1) is a high-performance real-time SMP kernel designed specifically for embedded applications. +``` +arc_hs_smp +cortex_a34_smp +cortex_a35_smp +cortex_a53_smp +cortex_a55_smp +cortex_a57_smp +cortex_a5x_smp +cortex_a5_smp +cortex_a65ae_smp +cortex_a65_smp +cortex_a72_smp +cortex_a73_smp +cortex_a75_smp +cortex_a76ae_smp +cortex_a76_smp +cortex_a77_smp +cortex_a78_smp +cortex_a7_smp +cortex_a9_smp +linux ``` -NOTE: You will have to take the dependency graph above into account when building anything other than threadx itself. +## Adaptation layer for ThreadX -# Repository Structure and Usage +Azure RTOS ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications. To help ease application migration to Azure RTOS, ThreadX provides [adaption layers](https://github.com/azure-rtos/threadx/tree/master/utility/rtos_compatibility_layers) for various legacy RTOS APIs (FreeRTOS, POSIX, OSEK, etc.). -## Branches & Releases +## Component dependencies -The master branch has the most recent code with all new features and bug fixes. It does not represent the latest General Availability (GA) release of the library. +The main components of Azure RTOS are each provided in their own repository, but there are dependencies between them, as shown in the following graph. This is important to understand when setting up your builds. -## Releases +![dependency graph](docs/deps.png) -Each official release (preview or GA) will be tagged to mark the commit and push it into the Github releases tab, e.g. `v6.0-rel`. +> You will have to take the dependency graph above into account when building anything other than ThreadX itself. -## Directory layout +### Building and using the library -``` -- cmake -- common - - inc - - src -- ports - - cortex_m0/gnu - - inc - - src - - cortex_m3/gnu - - inc - - src - - cortex_m4/gnu - - inc - - src - - cortex_m7/gnu - - inc - - src -- samples -``` +Instruction for building the ThreadX as static library using Arm GNU Toolchain and CMake. If you are using toolchain and IDE from semiconductor, you might follow its own instructions to use Azure RTOS components as explained in the [Getting Started](#getting-started) section. -# Security +1. Install the following tools: -Azure RTOS provides OEMs with components to secure communication and to create code and data isolation using underlying MCU/MPU hardware protection mechanisms. It is ultimately the responsibility of the device builder to ensure the device fully meets the evolving security requirements associated with its specific use case. + * [CMake](https://cmake.org/download/) version 3.0 or later + * [Arm GNU Toolchain for arm-none-eabi](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) + * [Ninja](https://ninja-build.org/) -# Adaptation layer for ThreadX +1. Cloning the repo -Azure RTOS ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications. To help ease application migration to Azure RTOS, ThreadX provides [adaption layers](https://github.com/azure-rtos/threadx/tree/master/utility/rtos_compatibility_layers) for various legacy RTOS APIs (FreeRTOS, POSIX, OSEK, etc.). + ```bash + $ git clone https://github.com/azure-rtos/threadx.git + ``` + +1. Define the features and addons you need in `tx_user.h` and build together with the component source code. You can refer to [`tx_user_sample.h`](https://github.com/azure-rtos/threadx/blob/master/common/inc/tx_user_sample.h) as an example. + +1. Building as a static library + + 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 `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. + + An example of building the library for Cortex-M4: -# Licensing + ```bash + $ cmake -Bbuild -GNinja -DCMAKE_TOOLCHAIN_FILE=cmake/cortex_m4.cmake . + + $ cmake --build ./build + ``` + +## Professional support + +[Professional support plans](https://azure.microsoft.com/support/options/) are available from Microsoft. For community support and others, see the [Resources](#resources) section below. + +## Licensing License terms for using Azure RTOS are defined in the LICENSE.txt file of this repo. Please refer to this file for all definitive licensing information. No additional license fees are required for deploying Azure RTOS on hardware defined in the LICENSED-HARDWARE.txt file. If you are using hardware not defined in the LICENSED-HARDWARE.txt file or have licensing questions in general, please contact Microsoft directly at https://aka.ms/azrtos-license. -# Contribution, feedback, issues, and professional support +## Resources -If you encounter any bugs, have suggestions for new features, or if you would like to become an active contributor to this project, please follow the instructions provided in the contribution guideline for the corresponding repo. +The following are references to additional Azure RTOS resources: -For basic support, click Issues in the command bar or post a question to [Stack Overflow](http://stackoverflow.com/questions/tagged/azure-rtos+threadx) using the `threadx` and `azure-rtos` tags. +- **Product introduction and white papers**: https://azure.com/rtos +- **General technical questions**: https://aka.ms/QnA/azure-rtos +- **Product issues and bugs, or feature requests**: https://github.com/azure-rtos/threadx/issues +- **Licensing and sales questions**: https://aka.ms/azrtos-license +- **Product roadmap and support policy**: https://aka.ms/azrtos/lts +- **Blogs and videos**: http://msiotblog.com and https://aka.ms/iotshow +- **Azure RTOS TraceX Installer**: https://aka.ms/azrtos-tracex-installer -Professional support plans (https://azure.microsoft.com/en-us/support/options/) are available from Microsoft. +You can also check [previous questions](https://stackoverflow.com/questions/tagged/azure-rtos+threadx) or ask new ones on StackOverflow using the `azure-rtos` and `threadx` tags. + +## Security + +Azure RTOS provides OEMs with components to secure communication and to create code and data isolation using underlying MCU/MPU hardware protection mechanisms. It is ultimately the responsibility of the device builder to ensure the device fully meets the evolving security requirements associated with its specific use case. -# Additional Resources +## Contribution -The following are references to additional Azure RTOS and Azure IoT in general: -| Content | Link | -|---|---| -| TraceX Installer | https://aka.ms/azrtos-tracex-installer | -| 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://aka.ms/azrtos-license | -| Azure RTOS Product Support Policy | https://aka.ms/azrtos/lts | -| Azure RTOS Functional Safety Artifacts | https://aka.ms/azrtos/tuv | -| For technical questions check out Microsoft Q/A for Azure IoT | https://aka.ms/QnA/azure-rtos | -| Internet of Things Show for latest announcements and online training | https://aka.ms/iotshow | -| IoT Tech Community | https://aka.ms/community/azure-rtos | +Please follow the instructions provided in the [CONTRIBUTING.md](./CONTRIBUTING.md) for the corresponding repository. \ No newline at end of file diff --git a/common/inc/tx_api.h b/common/inc/tx_api.h index d4d8e5006..9974c9771 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.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -89,6 +89,11 @@ /* 07-29-2022 Scott Larson Modified comment(s), */ /* update patch number, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Modified comment(s), */ +/* add extension macros, */ +/* update EPK typedef, */ +/* update version numbers, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -115,6 +120,9 @@ extern "C" { #include "tx_port.h" +#if (defined(TX_EXECUTION_PROFILE_ENABLE) && !defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY)) +#include "tx_execution_profile.h" +#endif /* Define basic constants for the ThreadX kernel. */ @@ -124,8 +132,8 @@ extern "C" { #define AZURE_RTOS_THREADX #define THREADX_MAJOR_VERSION 6 -#define THREADX_MINOR_VERSION 1 -#define THREADX_PATCH_VERSION 12 +#define THREADX_MINOR_VERSION 2 +#define THREADX_PATCH_VERSION 0 /* Define the following symbol for backward compatibility */ #define EL_PRODUCT_THREADX @@ -223,6 +231,76 @@ extern "C" { #define TX_FEATURE_NOT_ENABLED ((UINT) 0xFF) +#ifdef TX_64_BIT + +#ifndef TX_THREAD_EXTENSION_PTR_SET +#define TX_THREAD_EXTENSION_PTR_SET(a, b) { \ + TX_THREAD *thread_ptr; \ + thread_ptr = (TX_THREAD *) (a); \ + (thread_ptr -> tx_thread_extension_ptr) = (VOID *)(b); \ + } +#endif /* TX_THREAD_EXTENSION_PTR_SET */ + +#ifndef TX_THREAD_EXTENSION_PTR_GET +#define TX_THREAD_EXTENSION_PTR_GET(a, b, c) { \ + TX_PARAMETER_NOT_USED(c); \ + TX_THREAD *thread_ptr; \ + thread_ptr = tx_thread_identify(); \ + while(1)\ + { \ + if (thread_ptr -> tx_thread_extension_ptr) \ + { \ + (a) = (b *)(thread_ptr -> tx_thread_extension_ptr); \ + break; \ + } \ + tx_thread_sleep(1); \ + } \ + } +#endif /* TX_THREAD_EXTENSION_PTR_GET */ + +#ifndef TX_TIMER_EXTENSION_PTR_SET +#define TX_TIMER_EXTENSION_PTR_SET(a, b) { \ + TX_TIMER *timer_ptr; \ + timer_ptr = (TX_TIMER *) (a); \ + (timer_ptr -> tx_timer_internal.tx_timer_internal_extension_ptr) = (VOID *)(b); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_SET */ + +#ifndef TX_TIMER_EXTENSION_PTR_GET +#define TX_TIMER_EXTENSION_PTR_GET(a, b, c) { \ + TX_PARAMETER_NOT_USED(c); \ + if (!_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr) \ + return; \ + (a) = (b *)(_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_GET */ + +#else /* not 64 bit */ + +#ifndef TX_THREAD_EXTENSION_PTR_SET +#define TX_THREAD_EXTENSION_PTR_SET(a, b) +#endif /* TX_THREAD_EXTENSION_PTR_SET */ + +#ifndef TX_THREAD_EXTENSION_PTR_GET +#define TX_THREAD_EXTENSION_PTR_GET(a, b, c) { \ + (a) = (b *)(c); \ + } +#endif /* TX_THREAD_EXTENSION_PTR_GET */ + +#ifndef TX_TIMER_EXTENSION_PTR_SET +#define TX_TIMER_EXTENSION_PTR_SET(a, b) +#endif /* TX_TIMER_EXTENSION_PTR_SET */ + +#ifndef TX_TIMER_EXTENSION_PTR_GET +#define TX_TIMER_EXTENSION_PTR_GET(a, b, c) { \ + (a) = (b *)(c); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_GET */ + +#endif /* TX_64_BIT */ + + + /* Define the common timer tick reference for use by other middleware components. The default value is 10ms, but may be replaced by a port specific version in tx_port.h or by the user as a compilation option. */ @@ -529,8 +607,8 @@ typedef struct TX_THREAD_STRUCT For Azure RTOS 6, user shall use TX_EXECUTION_PROFILE_ENABLE instead of TX_ENABLE_EXECUTION_CHANGE_NOTIFY, and SHALL NOT add variables to TX_THREAD_EXTENSION_3. */ #if (defined(TX_EXECUTION_PROFILE_ENABLE) && !defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY)) - unsigned long long tx_thread_execution_time_total; - unsigned long long tx_thread_execution_time_last_start; + EXECUTION_TIME tx_thread_execution_time_total; + EXECUTION_TIME_SOURCE_TYPE tx_thread_execution_time_last_start; #endif /* Define suspension sequence number. This is used to ensure suspension is still valid when diff --git a/common/src/tx_event_flags_get.c b/common/src/tx_event_flags_get.c index aba42c6b9..3cc621782 100644 --- a/common/src/tx_event_flags_get.c +++ b/common/src/tx_event_flags_get.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_event_flags_get PORTABLE C */ -/* 6.1.11 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -79,6 +79,9 @@ /* 04-25-2022 Scott Larson Modified comment(s), */ /* handle 0 flags case, */ /* resulting in version 6.1.11 */ +/* 10-31-2022 Scott Larson Modified comment(s), always */ +/* return actual flags, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, @@ -125,6 +128,9 @@ UINT interrupted_set_request; /* Pickup current flags. */ current_flags = group_ptr -> tx_event_flags_group_current; + /* Return the actual event flags and apply delayed clearing. */ + *actual_flags_ptr = current_flags & ~group_ptr -> tx_event_flags_group_delayed_clear; + /* Apply the event flag option mask. */ and_request = (get_option & TX_AND); @@ -158,9 +164,6 @@ UINT interrupted_set_request; if (flags_satisfied != ((ULONG) 0)) { - /* Return the actual event flags that satisfied the request. */ - *actual_flags_ptr = current_flags; - /* Pickup the clear bit. */ clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK); @@ -221,9 +224,6 @@ UINT interrupted_set_request; /* Yes, this request can be handled immediately. */ - /* Return the actual event flags that satisfied the request. */ - *actual_flags_ptr = current_flags; - /* Pickup the clear bit. */ clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK); @@ -274,7 +274,7 @@ UINT interrupted_set_request; #endif else { - + /* flags_satisfied is 0. */ /* Determine if the request specifies suspension. */ if (wait_option != TX_NO_WAIT) { diff --git a/common_smp/inc/tx_api.h b/common_smp/inc/tx_api.h index 5bd9bd7ab..ba2ba0a7b 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.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -78,6 +78,10 @@ /* 07-29-2022 Scott Larson Modified comment(s), */ /* update patch number, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Modified comment(s), */ +/* add extension macros, */ +/* update version numbers, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -129,8 +133,8 @@ extern "C" { #define AZURE_RTOS_THREADX #define THREADX_MAJOR_VERSION 6 -#define THREADX_MINOR_VERSION 1 -#define THREADX_PATCH_VERSION 12 +#define THREADX_MINOR_VERSION 2 +#define THREADX_PATCH_VERSION 0 /* Define the following symbol for backward compatibility */ #define EL_PRODUCT_THREADX @@ -228,6 +232,76 @@ extern "C" { #define TX_FEATURE_NOT_ENABLED ((UINT) 0xFF) +#ifdef TX_64_BIT + +#ifndef TX_THREAD_EXTENSION_PTR_SET +#define TX_THREAD_EXTENSION_PTR_SET(a, b) { \ + TX_THREAD *thread_ptr; \ + thread_ptr = (TX_THREAD *) (a); \ + (thread_ptr -> tx_thread_extension_ptr) = (VOID *)(b); \ + } +#endif /* TX_THREAD_EXTENSION_PTR_SET */ + +#ifndef TX_THREAD_EXTENSION_PTR_GET +#define TX_THREAD_EXTENSION_PTR_GET(a, b, c) { \ + TX_PARAMETER_NOT_USED(c); \ + TX_THREAD *thread_ptr; \ + thread_ptr = tx_thread_identify(); \ + while(1)\ + { \ + if (thread_ptr -> tx_thread_extension_ptr) \ + { \ + (a) = (b *)(thread_ptr -> tx_thread_extension_ptr); \ + break; \ + } \ + tx_thread_sleep(1); \ + } \ + } +#endif /* TX_THREAD_EXTENSION_PTR_GET */ + +#ifndef TX_TIMER_EXTENSION_PTR_SET +#define TX_TIMER_EXTENSION_PTR_SET(a, b) { \ + TX_TIMER *timer_ptr; \ + timer_ptr = (TX_TIMER *) (a); \ + (timer_ptr -> tx_timer_internal.tx_timer_internal_extension_ptr) = (VOID *)(b); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_SET */ + +#ifndef TX_TIMER_EXTENSION_PTR_GET +#define TX_TIMER_EXTENSION_PTR_GET(a, b, c) { \ + TX_PARAMETER_NOT_USED(c); \ + if (!_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr) \ + return; \ + (a) = (b *)(_tx_timer_expired_timer_ptr -> tx_timer_internal_extension_ptr); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_GET */ + +#else /* not 64 bit */ + +#ifndef TX_THREAD_EXTENSION_PTR_SET +#define TX_THREAD_EXTENSION_PTR_SET(a, b) +#endif /* TX_THREAD_EXTENSION_PTR_SET */ + +#ifndef TX_THREAD_EXTENSION_PTR_GET +#define TX_THREAD_EXTENSION_PTR_GET(a, b, c) { \ + (a) = (b *)(c); \ + } +#endif /* TX_THREAD_EXTENSION_PTR_GET */ + +#ifndef TX_TIMER_EXTENSION_PTR_SET +#define TX_TIMER_EXTENSION_PTR_SET(a, b) +#endif /* TX_TIMER_EXTENSION_PTR_SET */ + +#ifndef TX_TIMER_EXTENSION_PTR_GET +#define TX_TIMER_EXTENSION_PTR_GET(a, b, c) { \ + (a) = (b *)(c); \ + } +#endif /* TX_TIMER_EXTENSION_PTR_GET */ + +#endif /* TX_64_BIT */ + + + /* Define the common timer tick reference for use by other middleware components. The default value is 10ms, but may be replaced by a port specific version in tx_port.h or by the user as a compilation option. */ diff --git a/common_smp/src/tx_event_flags_get.c b/common_smp/src/tx_event_flags_get.c index aba42c6b9..3cc621782 100644 --- a/common_smp/src/tx_event_flags_get.c +++ b/common_smp/src/tx_event_flags_get.c @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_event_flags_get PORTABLE C */ -/* 6.1.11 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -79,6 +79,9 @@ /* 04-25-2022 Scott Larson Modified comment(s), */ /* handle 0 flags case, */ /* resulting in version 6.1.11 */ +/* 10-31-2022 Scott Larson Modified comment(s), always */ +/* return actual flags, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ UINT _tx_event_flags_get(TX_EVENT_FLAGS_GROUP *group_ptr, ULONG requested_flags, @@ -125,6 +128,9 @@ UINT interrupted_set_request; /* Pickup current flags. */ current_flags = group_ptr -> tx_event_flags_group_current; + /* Return the actual event flags and apply delayed clearing. */ + *actual_flags_ptr = current_flags & ~group_ptr -> tx_event_flags_group_delayed_clear; + /* Apply the event flag option mask. */ and_request = (get_option & TX_AND); @@ -158,9 +164,6 @@ UINT interrupted_set_request; if (flags_satisfied != ((ULONG) 0)) { - /* Return the actual event flags that satisfied the request. */ - *actual_flags_ptr = current_flags; - /* Pickup the clear bit. */ clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK); @@ -221,9 +224,6 @@ UINT interrupted_set_request; /* Yes, this request can be handled immediately. */ - /* Return the actual event flags that satisfied the request. */ - *actual_flags_ptr = current_flags; - /* Pickup the clear bit. */ clear_request = (get_option & TX_EVENT_FLAGS_CLEAR_MASK); @@ -274,7 +274,7 @@ UINT interrupted_set_request; #endif else { - + /* flags_satisfied is 0. */ /* Determine if the request specifies suspension. */ if (wait_option != TX_NO_WAIT) { diff --git a/common_smp/src/tx_thread_create.c b/common_smp/src/tx_thread_create.c index a99af7e6c..2c799a9b5 100644 --- a/common_smp/src/tx_thread_create.c +++ b/common_smp/src/tx_thread_create.c @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_create PORTABLE SMP */ -/* 6.1.8 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -85,6 +85,10 @@ /* resulting in version 6.1.3 */ /* 08-02-2021 Scott Larson Removed unneeded cast, */ /* resulting in version 6.1.8 */ +/* 10-31-2022 Scott Larson Removed ifdef block to always */ +/* restore interrupts at end */ +/* of if block, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ UINT _tx_thread_create(TX_THREAD *thread_ptr, CHAR *name_ptr, @@ -344,11 +348,8 @@ ALIGN_TYPE updated_stack_start; #endif } -#ifndef TX_NOT_INTERRUPTABLE - /* Restore interrupts. */ TX_RESTORE -#endif } else { diff --git a/docs/threadx-features.png b/docs/threadx-features.png new file mode 100644 index 000000000..096a3e08b Binary files /dev/null and b/docs/threadx-features.png differ diff --git a/ports/cortex_m23/iar/src/tx_misra.s b/ports/cortex_m23/iar/src/tx_misra.s index 11b2a1c7b..f8f10da0b 100644 --- a/ports/cortex_m23/iar/src/tx_misra.s +++ b/ports/cortex_m23/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m3/iar/src/tx_misra.s b/ports/cortex_m3/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m3/iar/src/tx_misra.s +++ b/ports/cortex_m3/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m33/iar/src/tx_misra.s b/ports/cortex_m33/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m33/iar/src/tx_misra.s +++ b/ports/cortex_m33/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m4/iar/src/tx_misra.s b/ports/cortex_m4/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m4/iar/src/tx_misra.s +++ b/ports/cortex_m4/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m55/ac6/example_build/AzureRTOS.uvmpw b/ports/cortex_m55/ac6/example_build/AzureRTOS.uvmpw new file mode 100644 index 000000000..2680c460f --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/AzureRTOS.uvmpw @@ -0,0 +1,26 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + WorkSpace + + + .\demo_secure_zone\demo_secure_zone.uvprojx + 1 + 1 + + + + .\demo_threadx_non-secure_zone\demo_threadx_non-secure_zone.uvprojx + 1 + + + + .\ThreadX_Library.uvprojx + 1 + + +
diff --git a/ports/cortex_m55/ac6/example_build/CS300_ac6.sct b/ports/cortex_m55/ac6/example_build/CS300_ac6.sct new file mode 100644 index 000000000..a22738d24 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/CS300_ac6.sct @@ -0,0 +1,137 @@ +#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m55 -xc +; command above MUST be in first line (no comment above!) + +;Note: Add '-mcmse' to first line if your software model is "Secure Mode". +; #! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m85 -xc -mcmse + + +/* +;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- +*/ + +/* + ID From To Alias Security NSC + 1 0x0000_0000 0x000F_FFFF 1MB Code ITCM 4 NS n/a + 2 0x0010_0000 0x002F_FFFF 2MB Code SRAM (only 2MB) 5 NS n/a + 4 0x1000_0000 0x100F_FFFF 1MB Code ITCM 1 S n/a + 5 0x1100_0000 0x102F_FFFF 2MB Code SRAM (only 2MB) 2 S CODE NSC + 7 0x2000_0000 0x203F_FFFF 4MB SRAM DTCM (4 x 1MB) 11 NS n/a + 11 0x3000_0000 0x303F_FFFF 4MB SRAM DTCM (4 x 1MB) 7 S n/a +*/ + + +/*--------------------- Flash Configuration ---------------------------------- +; Flash Configuration +; Flash Base Address <0x0-0xFFFFFFFF:8> +; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __ROM_BASE 0x00080000 +#define __ROM_SIZE 0x00080000 + +/*--------------------- Embedded RAM Configuration --------------------------- +; RAM Configuration +; RAM Base Address <0x0-0xFFFFFFFF:8> +; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __RAM_BASE 0x20080000 +#define __RAM_SIZE 0x00080000 + +/*--------------------- Stack / Heap Configuration --------------------------- +; Stack / Heap Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __STACK_SIZE 0x00000400 +#define __HEAP_SIZE 0x00000C00 + +/*--------------------- CMSE Veneer Configuration --------------------------- +; CMSE Veneer Configuration +; CMSE VeneerBase Address <0x0-0xFFFFFFFF:8> +; 0xFFFFFFFF: Place Veneers at the end of Flash (default) +; CMSE Veneer Size (in Bytes) <0x0-0xFFFFFFFF:32> +; + *----------------------------------------------------------------------------*/ +#define __CMSEVENEER_BASE 0x10100000 +#define __CMSEVENEER_SIZE 0x00000400 + +/* +;------------- <<< end of configuration section >>> --------------------------- +*/ + + +/*---------------------------------------------------------------------------- + User Stack & Heap boundary definition + *----------------------------------------------------------------------------*/ +#define __STACK_TOP (__RAM_BASE + __RAM_SIZE - __STACKSEAL_SIZE) /* starts at end of RAM - 8 byte stack seal */ +#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ + +/* ---------------------------------------------------------------------------- + Stack seal size definition + *----------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define __STACKSEAL_SIZE ( 8 ) +#else +#define __STACKSEAL_SIZE ( 0 ) +#endif + + +/*---------------------------------------------------------------------------- + Region base & size definition + *----------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#if defined (__CMSEVENEER_BASE) && (__CMSEVENEER_BASE == 0xFFFFFFFF) +#define __CV_BASE ( __ROM_BASE + __ROM_SIZE - __CMSEVENEER_SIZE ) +#else +#define __CV_BASE ( __CMSEVENEER_BASE ) +#endif +#define __CV_SIZE ( __CMSEVENEER_SIZE ) +#else +#define __CV_SIZE ( 0 ) +#endif + +#define __RO_BASE ( __ROM_BASE ) +#define __RO_SIZE ( __ROM_SIZE - __CV_SIZE ) + +#define __RW_BASE ( __RAM_BASE ) +#define __RW_SIZE ( __RAM_SIZE - __STACK_SIZE - __HEAP_SIZE ) + + +/*---------------------------------------------------------------------------- + Scatter Region definition + *----------------------------------------------------------------------------*/ +LR_ROM __RO_BASE __RO_SIZE { ; load region size_region + ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_RAM __RW_BASE __RW_SIZE { ; RW data + .ANY (+RW +ZI) + } + +#if __HEAP_SIZE > 0 + ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap + } +#endif + + ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + STACKSEAL +0 EMPTY __STACKSEAL_SIZE { ; Reserve empty region for stack seal immediately after stack + } +#endif +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +LR_CMSE_VENEER __CV_BASE ALIGN 32 __CV_SIZE { ; own load/execution region for CMSE Veneers + ER_CMSE_VENEER __CV_BASE __CV_SIZE { + *(Veneer$$CMSE) + } +} +#endif diff --git a/ports/cortex_m55/ac6/example_build/CS300_ac6_s.sct b/ports/cortex_m55/ac6/example_build/CS300_ac6_s.sct new file mode 100644 index 000000000..ad3a38969 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/CS300_ac6_s.sct @@ -0,0 +1,137 @@ +#! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m55 -xc -mcmse +; command above MUST be in first line (no comment above!) + +;Note: Add '-mcmse' to first line if your software model is "Secure Mode". +; #! armclang -E --target=arm-arm-none-eabi -mcpu=cortex-m85 -xc -mcmse + + +/* +;-------- <<< Use Configuration Wizard in Context Menu >>> ------------------- +*/ + +/* + ID From To Alias Security NSC + 1 0x0000_0000 0x000F_FFFF 1MB Code ITCM 4 NS n/a + 2 0x0010_0000 0x002F_FFFF 2MB Code SRAM (only 2MB) 5 NS n/a + 4 0x1000_0000 0x100F_FFFF 1MB Code ITCM 1 S n/a + 5 0x1100_0000 0x102F_FFFF 2MB Code SRAM (only 2MB) 2 S CODE NSC + 7 0x2000_0000 0x203F_FFFF 4MB SRAM DTCM (4 x 1MB) 11 NS n/a + 11 0x3000_0000 0x303F_FFFF 4MB SRAM DTCM (4 x 1MB) 7 S n/a +*/ + + +/*--------------------- Flash Configuration ---------------------------------- +; Flash Configuration +; Flash Base Address <0x0-0xFFFFFFFF:8> +; Flash Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __ROM_BASE 0x10000000 +#define __ROM_SIZE 0x00080000 + +/*--------------------- Embedded RAM Configuration --------------------------- +; RAM Configuration +; RAM Base Address <0x0-0xFFFFFFFF:8> +; RAM Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __RAM_BASE 0x30000000 +#define __RAM_SIZE 0x00080000 + +/*--------------------- Stack / Heap Configuration --------------------------- +; Stack / Heap Configuration +; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> +; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> +; + *----------------------------------------------------------------------------*/ +#define __STACK_SIZE 0x00000400 +#define __HEAP_SIZE 0x00000C00 + +/*--------------------- CMSE Veneer Configuration --------------------------- +; CMSE Veneer Configuration +; CMSE VeneerBase Address <0x0-0xFFFFFFFF:8> +; 0xFFFFFFFF: Place Veneers at the end of Flash (default) +; CMSE Veneer Size (in Bytes) <0x0-0xFFFFFFFF:32> +; + *----------------------------------------------------------------------------*/ +#define __CMSEVENEER_BASE 0x11000000 +#define __CMSEVENEER_SIZE 0x00000400 + +/* +;------------- <<< end of configuration section >>> --------------------------- +*/ + + +/*---------------------------------------------------------------------------- + User Stack & Heap boundary definition + *----------------------------------------------------------------------------*/ +#define __STACK_TOP (__RAM_BASE + __RAM_SIZE - __STACKSEAL_SIZE) /* starts at end of RAM - 8 byte stack seal */ +#define __HEAP_BASE (AlignExpr(+0, 8)) /* starts after RW_RAM section, 8 byte aligned */ + +/* ---------------------------------------------------------------------------- + Stack seal size definition + *----------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#define __STACKSEAL_SIZE ( 8 ) +#else +#define __STACKSEAL_SIZE ( 0 ) +#endif + + +/*---------------------------------------------------------------------------- + Region base & size definition + *----------------------------------------------------------------------------*/ +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +#if defined (__CMSEVENEER_BASE) && (__CMSEVENEER_BASE == 0xFFFFFFFF) +#define __CV_BASE ( __ROM_BASE + __ROM_SIZE - __CMSEVENEER_SIZE ) +#else +#define __CV_BASE ( __CMSEVENEER_BASE ) +#endif +#define __CV_SIZE ( __CMSEVENEER_SIZE ) +#else +#define __CV_SIZE ( 0 ) +#endif + +#define __RO_BASE ( __ROM_BASE ) +#define __RO_SIZE ( __ROM_SIZE - __CV_SIZE ) + +#define __RW_BASE ( __RAM_BASE ) +#define __RW_SIZE ( __RAM_SIZE - __STACK_SIZE - __HEAP_SIZE ) + + +/*---------------------------------------------------------------------------- + Scatter Region definition + *----------------------------------------------------------------------------*/ +LR_ROM __RO_BASE __RO_SIZE { ; load region size_region + ER_ROM __RO_BASE __RO_SIZE { ; load address = execution address + *.o (RESET, +First) + *(InRoot$$Sections) + .ANY (+RO) + .ANY (+XO) + } + + RW_RAM __RW_BASE __RW_SIZE { ; RW data + .ANY (+RW +ZI) + } + +#if __HEAP_SIZE > 0 + ARM_LIB_HEAP __HEAP_BASE EMPTY __HEAP_SIZE { ; Reserve empty region for heap + } +#endif + + ARM_LIB_STACK __STACK_TOP EMPTY -__STACK_SIZE { ; Reserve empty region for stack + } + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + STACKSEAL +0 EMPTY __STACKSEAL_SIZE { ; Reserve empty region for stack seal immediately after stack + } +#endif +} + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) +LR_CMSE_VENEER __CV_BASE ALIGN 32 __CV_SIZE { ; own load/execution region for CMSE Veneers + ER_CMSE_VENEER __CV_BASE __CV_SIZE { + *(Veneer$$CMSE) + } +} +#endif diff --git a/ports/cortex_m55/ac6/example_build/CS300_config.txt b/ports/cortex_m55/ac6/example_build/CS300_config.txt new file mode 100644 index 000000000..c9732696c --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/CS300_config.txt @@ -0,0 +1,19 @@ +# Parameters: +# instance.parameter=value #(type, mode) default = 'def value' : description : [min..max] +#------------------------------------------------------------------------------ +cpu0.semihosting-enable=0 # (bool , init-time) default = '1' : Enable semihosting SVC traps. Applications that do not use semihosting must set this parameter to false. +#cpu0.cpi_div=1 # (int , run-time ) default = '0x1' : divider for calculating CPI (Cycles Per Instruction) +#cpu0.cpi_mul=1 # (int , run-time ) default = '0x1' : multiplier for calculating CPI (Cycles Per Instruction) +#cpu0.min_sync_level=3 # (int , run-time ) default = '0x0' : force minimum syncLevel (0=off=default,1=syncState,2=postInsnIO,3=postInsnAll) +cpu0.FPU=1 # (bool , init-time) default = '1' : Set whether the model has VFP support +cpu0.MVE=2 # (int , init-time) default = '0x1' : Set whether the model has MVE support. If FPU = 0: 0=MVE not included, 1=Integer subset of MVE included. If FPU = 1: 0=MVE not included, 1=Integer subset of MVE included, 2=Integer and half and single precision floating point MVE included +#cpu0.SAU=8 # (int , init-time) default = '0x8' : Number of SAU regions (0 => no SAU) +#cpu0.SECEXT=1 # (bool , init-time) default = '1' : Whether the ARMv8-M Security Extensions are included +#cpu0.INITSVTOR=0x10000000 # (int , init-time) default = '0x10000000' : Secure vector-table offset at reset +#cpu0.INITNSVTOR=0x00000000 # (int , init-time) default = '0x0' : Non-Secure vector-table offset at reset +#NSC_CFG_0=1 # (bool , init-time) default = '0' : Whether 0x10000000..0x1FFFFFFF is non-secure-callable +#NSC_CFG_1=0 # (bool , init-time) default = '0' : Whether 0x30000000..0x3FFFFFFF is non-secure-callable +#mps3_board.platform_type=1 # (int , init-time) default = '0x1' : 0:Original MPS3; 1:SSE-300 +mps3_board.visualisation.disable-visualisation=1 # (bool , init-time) default = '0' : Enable/disable visualisation +#cpu_core.mps3_board.DISABLE_GATING=1 # (bool , init-time) default = '0' : Disable Memory gating logic +#------------------------------------------------------------------------------ diff --git a/ports/cortex_m55/ac6/example_build/Debug.ini b/ports/cortex_m55/ac6/example_build/Debug.ini new file mode 100644 index 000000000..4feb660c2 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/Debug.ini @@ -0,0 +1,4 @@ +LOAD "..\\demo_threadx_non-secure_zone\\Objects\\demo_threadx_non-secure_zone.axf" incremental +LOAD "..\\demo_secure_zone\\Objects\\secure_app.axf" incremental +RESET +g, \\secure_app\main_s\main \ No newline at end of file diff --git a/ports/cortex_m55/ac6/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h b/ports/cortex_m55/ac6/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h new file mode 100644 index 000000000..2ec1c863b --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/RTE/_ThreadX_Library_Project/RTE_Components.h @@ -0,0 +1,21 @@ + +/* + * Auto generated Run-Time-Environment Configuration File + * *** Do not modify ! *** + * + * Project: 'ThreadX_Library' + * Target: 'ThreadX_Library_Project' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "ARMCM55.h" + + + +#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m55/ac6/example_build/RTOS.uvmpw.uvgui b/ports/cortex_m55/ac6/example_build/RTOS.uvmpw.uvgui new file mode 100644 index 000000000..5c23c31fc --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/RTOS.uvmpw.uvgui @@ -0,0 +1,1777 @@ + + + + -6.1 + +
### uVision Project, (C) Keil Software
+ + + + + 44 + 2 + 3 + + -1 + -1 + + + -1 + -1 + + + 0 + 0 + 1024 + 728 + + + + 0 + + 297 + 0100000004000000010000000100000001000000010000000000000002000000000000000100000001000000000000002800000028000000010000000100000000000000010000005F433A5C4B65696C5C41524D5C5041434B5C41524D5C434D5349535C352E322E305C434D5349535C52544F53325C5254585C4578616D706C65735C54727573745A6F6E6556384D5C52544F535C434D33335F735C41627374726163742E747874000000000C41627374726163742E74787400000000C5D4F200FFFFFFFF0100000010000000C5D4F200FFDC7800BECEA100F0A0A100BCA8E1009CC1B600F7B88600D9ADC200A5C2D700B3A6BE00EAD6A300F6FA7D00B5E99D005FC3CF00C1838300CACAD500010000000000000002000000380100006500000080070000FD030000 + + + + 0 + Build + + -1 + -1 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F40000004F00000090050000F0000000 + + + 16 + F4000000650000009005000006010000 + + + + 1005 + 1005 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000031010000CE030000 + + + 16 + 2100000037000000110100001A010000 + + + + 109 + 109 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000031010000CE030000 + + + 16 + 21000000370000003D010000BD020000 + + + + 1465 + 1465 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1466 + 1466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1467 + 1467 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1468 + 1468 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1506 + 1506 + 0 + 0 + 0 + 0 + 32767 + 0 + 16384 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 1913 + 1913 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1935 + 1935 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000110100001A010000 + + + + 1936 + 1936 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000110100001A010000 + + + + 1937 + 1937 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000110100001A010000 + + + + 1939 + 1939 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1940 + 1940 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1941 + 1941 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 1942 + 1942 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 195 + 195 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000031010000CE030000 + + + 16 + 21000000370000003D010000BD020000 + + + + 196 + 196 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000031010000CE030000 + + + 16 + 21000000370000003D010000BD020000 + + + + 197 + 197 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 03000000390300007D070000CE030000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 198 + 198 + 0 + 0 + 0 + 0 + 32767 + 0 + 32768 + 0 + + 16 + 000000005F0200009005000014030000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 199 + 199 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000390300007D070000CE030000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 203 + 203 + 0 + 0 + 0 + 0 + 32767 + 0 + 8192 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 204 + 204 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 221 + 221 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000000000000000000000000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 2506 + 2506 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 2507 + 2507 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 343 + 343 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 346 + 346 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 35824 + 35824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + F7000000660000008D050000D7000000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 35885 + 35885 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35886 + 35886 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35887 + 35887 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35888 + 35888 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35889 + 35889 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35890 + 35890 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35891 + 35891 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35892 + 35892 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35893 + 35893 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35894 + 35894 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35895 + 35895 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35896 + 35896 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35897 + 35897 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35898 + 35898 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35899 + 35899 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35900 + 35900 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35901 + 35901 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35902 + 35902 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35903 + 35903 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35904 + 35904 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 35905 + 35905 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 38003 + 38003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006600000031010000CE030000 + + + 16 + 21000000370000003D010000BD020000 + + + + 38007 + 38007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000390300007D070000CE030000 + + + 16 + 2100000037000000E9020000D8000000 + + + + 436 + 436 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000390300007D070000CE030000 + + + 16 + 21000000370000003D010000BD020000 + + + + 437 + 437 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000110100001A010000 + + + + 440 + 440 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000760200008D050000FB020000 + + + 16 + 2100000037000000110100001A010000 + + + + 463 + 463 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006E0300007D070000CE030000 + + + 16 + 21000000370000003D01000079020000 + + + + 466 + 466 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 030000006E0300007D070000CE030000 + + + 16 + 21000000370000003D01000079020000 + + + + 470 + 470 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000010000000300000003020000 + + + 16 + 2100000037000000E9020000C7000000 + + + + 50000 + 50000 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50001 + 50001 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50002 + 50002 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50003 + 50003 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50004 + 50004 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50005 + 50005 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50006 + 50006 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50007 + 50007 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50008 + 50008 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50009 + 50009 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50010 + 50010 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50011 + 50011 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50012 + 50012 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50013 + 50013 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50014 + 50014 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50015 + 50015 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50016 + 50016 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50017 + 50017 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50018 + 50018 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 50019 + 50019 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + A3040000660000008D05000056020000 + + + 16 + 2100000037000000110100001A010000 + + + + 59392 + 59392 + 1 + 0 + 0 + 0 + 940 + 0 + 8192 + 0 + + 16 + 0000000000000000B70300001C000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59393 + 0 + 1 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 00000000E703000080070000FA030000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59399 + 59399 + 1 + 0 + 0 + 0 + 303 + 0 + 8192 + 1 + + 16 + 000000001C000000E701000038000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 59400 + 59400 + 0 + 0 + 0 + 0 + 612 + 0 + 8192 + 2 + + 16 + 00000000380000006F02000054000000 + + + 16 + 0A0000000A0000006E0000006E000000 + + + + 824 + 824 + 0 + 0 + 0 + 0 + 32767 + 0 + 4096 + 0 + + 16 + 03000000010000000300000003020000 + + + 16 + 21000000370000001101000002010000 + + + + 3692 + 000000000F000000000000000020000000000000FFFFFFFFFFFFFFFFF4000000F000000090050000F4000000000000000100000004000000010000000000000000000000FFFFFFFF06000000CB00000057010000CC000000F08B00005A01000079070000FFFF02000B004354616262656450616E650020000000000000F4000000650000009005000006010000F40000004F00000090050000F00000000000000040280046060000000B446973617373656D626C7900000000CB00000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A6572000000005701000001000000FFFFFFFFFFFFFFFF14506572666F726D616E636520416E616C797A657200000000CC00000001000000FFFFFFFFFFFFFFFF0E4C6F67696320416E616C797A657200000000F08B000001000000FFFFFFFFFFFFFFFF0D436F646520436F766572616765000000005A01000001000000FFFFFFFFFFFFFFFF11496E737472756374696F6E205472616365000000007907000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFCB00000001000000FFFFFFFFCB000000000000000040000000000000FFFFFFFFFFFFFFFF9C0400004F000000A00400006F020000000000000200000004000000010000000000000000000000FFFFFFFF2B000000E2050000CA0900002D8C00002E8C00002F8C0000308C0000318C0000328C0000338C0000348C0000358C0000368C0000378C0000388C0000398C00003A8C00003B8C00003C8C00003D8C00003E8C00003F8C0000408C0000418C000050C3000051C3000052C3000053C3000054C3000055C3000056C3000057C3000058C3000059C300005AC300005BC300005CC300005DC300005EC300005FC3000060C3000061C3000062C3000063C3000001800040000000000000A0040000650000009005000085020000A00400004F000000900500006F02000000000000404100462B0000000753796D626F6C7300000000E205000001000000FFFFFFFFFFFFFFFF0A5472616365204461746100000000CA09000001000000FFFFFFFFFFFFFFFF00000000002D8C000001000000FFFFFFFFFFFFFFFF00000000002E8C000001000000FFFFFFFFFFFFFFFF00000000002F8C000001000000FFFFFFFFFFFFFFFF0000000000308C000001000000FFFFFFFFFFFFFFFF0000000000318C000001000000FFFFFFFFFFFFFFFF0000000000328C000001000000FFFFFFFFFFFFFFFF0000000000338C000001000000FFFFFFFFFFFFFFFF0000000000348C000001000000FFFFFFFFFFFFFFFF0000000000358C000001000000FFFFFFFFFFFFFFFF0000000000368C000001000000FFFFFFFFFFFFFFFF0000000000378C000001000000FFFFFFFFFFFFFFFF0000000000388C000001000000FFFFFFFFFFFFFFFF0000000000398C000001000000FFFFFFFFFFFFFFFF00000000003A8C000001000000FFFFFFFFFFFFFFFF00000000003B8C000001000000FFFFFFFFFFFFFFFF00000000003C8C000001000000FFFFFFFFFFFFFFFF00000000003D8C000001000000FFFFFFFFFFFFFFFF00000000003E8C000001000000FFFFFFFFFFFFFFFF00000000003F8C000001000000FFFFFFFFFFFFFFFF0000000000408C000001000000FFFFFFFFFFFFFFFF0000000000418C000001000000FFFFFFFFFFFFFFFF000000000050C3000001000000FFFFFFFFFFFFFFFF000000000051C3000001000000FFFFFFFFFFFFFFFF000000000052C3000001000000FFFFFFFFFFFFFFFF000000000053C3000001000000FFFFFFFFFFFFFFFF000000000054C3000001000000FFFFFFFFFFFFFFFF000000000055C3000001000000FFFFFFFFFFFFFFFF000000000056C3000001000000FFFFFFFFFFFFFFFF000000000057C3000001000000FFFFFFFFFFFFFFFF000000000058C3000001000000FFFFFFFFFFFFFFFF000000000059C3000001000000FFFFFFFFFFFFFFFF00000000005AC3000001000000FFFFFFFFFFFFFFFF00000000005BC3000001000000FFFFFFFFFFFFFFFF00000000005CC3000001000000FFFFFFFFFFFFFFFF00000000005DC3000001000000FFFFFFFFFFFFFFFF00000000005EC3000001000000FFFFFFFFFFFFFFFF00000000005FC3000001000000FFFFFFFFFFFFFFFF000000000060C3000001000000FFFFFFFFFFFFFFFF000000000061C3000001000000FFFFFFFFFFFFFFFF000000000062C3000001000000FFFFFFFFFFFFFFFF000000000063C3000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFE205000001000000FFFFFFFFE2050000000000000010000001000000FFFFFFFFFFFFFFFF340100004F00000038010000E703000001000000020000100400000001000000A7FEFFFF1C060000FFFFFFFF05000000ED0300006D000000C3000000C40000007394000001800010000001000000000000006500000034010000FD030000000000004F00000034010000E70300000000000040410056050000000750726F6A65637401000000ED03000001000000FFFFFFFFFFFFFFFF05426F6F6B73010000006D00000001000000FFFFFFFFFFFFFFFF0946756E6374696F6E7301000000C300000001000000FFFFFFFFFFFFFFFF0954656D706C6174657301000000C400000001000000FFFFFFFFFFFFFFFF09526567697374657273000000007394000001000000FFFFFFFFFFFFFFFF00000000000000000000000000000000000000000000000001000000FFFFFFFFED03000001000000FFFFFFFFED030000000000000080000000000000FFFFFFFFFFFFFFFF000000005B020000900500005F02000000000000010000000400000001000000000000000000000000000000000000000000000001000000C6000000FFFFFFFF0E0000008F070000930700009407000095070000960700009007000091070000B5010000B8010000B9050000BA050000BB050000BC050000CB090000018000800000000000000000000075020000900500002A030000000000005F020000900500001403000000000000404100460E0000001343616C6C20537461636B202B204C6F63616C73000000008F07000001000000FFFFFFFFFFFFFFFF0755415254202331000000009307000001000000FFFFFFFFFFFFFFFF0755415254202332000000009407000001000000FFFFFFFFFFFFFFFF0755415254202333000000009507000001000000FFFFFFFFFFFFFFFF15446562756720287072696E74662920566965776572000000009607000001000000FFFFFFFFFFFFFFFF0757617463682031000000009007000001000000FFFFFFFFFFFFFFFF0757617463682032000000009107000001000000FFFFFFFFFFFFFFFF10547261636520457863657074696F6E7300000000B501000001000000FFFFFFFFFFFFFFFF0E4576656E7420436F756E7465727300000000B801000001000000FFFFFFFFFFFFFFFF084D656D6F7279203100000000B905000001000000FFFFFFFFFFFFFFFF084D656D6F7279203200000000BA05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203300000000BB05000001000000FFFFFFFFFFFFFFFF084D656D6F7279203400000000BC05000001000000FFFFFFFFFFFFFFFF105472616365204E617669676174696F6E00000000CB09000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200005F020000CC0200001403000000000000020000000400000000000000000000000000000000000000000000000000000002000000C6000000FFFFFFFF8F07000001000000FFFFFFFF8F07000001000000C6000000000000000080000000000000FFFFFFFFFFFFFFFF000000001E03000080070000220300000000000001000000040000000100000067FDFFFFF4000000FFFFFFFF04000000C5000000C7000000B40100007794000001800080000000000000000000003803000080070000FD030000000000002203000080070000E70300000000000040820046040000000C4275696C64204F757470757400000000C500000001000000FFFFFFFFFFFFFFFF0D46696E6420496E2046696C657300000000C700000001000000FFFFFFFFFFFFFFFF0A4572726F72204C69737400000000B401000001000000FFFFFFFFFFFFFFFF0742726F77736572000000007794000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFC500000001000000FFFFFFFFC5000000000000000080000000000000FFFFFFFFFFFFFFFF0000000017020000900500001B0200000000000001000000040000000100000000000000000000000000000000000000000000000100000000000000FFFFFFFF0200000038030000D6010000018000800000000000000000000000000000010000003202000000000000EAFFFFFF010000001C02000000000000404100460200000009554C494E4B706C7573000000003803000001000000FFFFFFFFFFFFFFFF0F53797374656D20416E616C797A657200000000D601000001000000FFFFFFFFFFFFFFFFFFFFFFFF0000000001000000000000000000000001000000FFFFFFFFC80200001B020000CC020000BF02000000000000020000000400000000000000000000000000000000000000000000000000000001000000FFFFFFFF3803000001000000FFFFFFFF38030000000000000080000000000000FFFFFFFFFFFFFFFF00000000530300008007000057030000000000000100000004000000010000000000000000000000FFFFFFFF02000000D2010000CF01000001800080000000000000000000006D03000080070000FD030000000000005703000080070000E70300000000000040820046020000000E536F757263652042726F7773657200000000D201000001000000FFFFFFFFFFFFFFFF1346696E6420416C6C205265666572656E63657300000000CF01000001000000FFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000000000000000000001000000FFFFFFFFD201000001000000FFFFFFFFD2010000000000000000000000000000 + + + 59392 + File + + 2438 + 00200000010000002800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000040004000000000000000000000000000000000100000001000000018022E100000000040005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000004000700000000000000000000000000000000010000000100000001802CE10000000004000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000004000900000000000000000000000000000000010000000100000001807B8A0000000004000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000004000C0000000000000000000000000000000001000000010000000180F4B00000000004000D000000000000000000000000000000000100000001000000018036B10000000004000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF88000000000400460000000000000000000000000000000001000000010000000180FE880000000004004500000000000000000000000000000000010000000100000001800B810000000004001300000000000000000000000000000000010000000100000001800C810000000004001400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F0880000020000000F000000000000000000000000000000000100000001000000FFFF0100120043555646696E64436F6D626F427574746F6EE803000000000000000000000000000000000000000000000001000000010000009600000002002050000000000944657374726F796564960000000000000014000944657374726F79656406507265656D7006746872656164136F735274785468726561645265616479507574106F73527478546872656164426C6F636B15457672527478546872656164556E626C6F636B656413457672527478546872656164426C6F636B6564116F735274785468726561645377697463681545767252747854687265616444657374726F796564146F7352747854687265616457616974456E746572146F7352747854687265616444656C61795469636B0D7468726561642D3E7374617465126F73527478546872656164426C6F636B6564126F7352747854687265616457616974696E67204576745274784B65726E656C496E666F5265747269657665645F44657461696C194576745274784B65726E656C496E666F52657472696576656408546872656164437206236966646566136F735F69646C655F7468726561645F617474720E6F73546872656164417474725F740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018024E10000000000001100000000000000000000000000000000010000000100000001800A810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000020000001500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000160000000000000000000000000000000001000000010000000180C988000000000400180000000000000000000000000000000001000000010000000180C788000000000000190000000000000000000000000000000001000000010000000180C8880000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E4C010000020001001A0000000F2650726F6A6563742057696E646F77000000000000000000000000010000000100000000000000000000000100000008002880DD880000000000001A0000000750726F6A656374000000000000000000000000010000000100000000000000000000000100000000002880DC8B0000000000003A00000005426F6F6B73000000000000000000000000010000000100000000000000000000000100000000002880E18B0000000000003B0000000946756E6374696F6E73000000000000000000000000010000000100000000000000000000000100000000002880E28B000000000000400000000954656D706C6174657300000000000000000000000001000000010000000000000000000000010000000000288018890000000000003D0000000E536F757263652042726F777365720000000000000000000000000100000001000000000000000000000001000000000028800000000000000400FFFFFFFF00000000000000000001000000000000000100000000000000000000000100000000002880D988000000000000390000000C4275696C64204F7574707574000000000000000000000000010000000100000000000000000000000100000000002880E38B000000000000410000000B46696E64204F75747075740000000000000000000000000100000001000000000000000000000001000000000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001B000000000000000000000000000000000100000001000000000000000446696C65AC030000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E1000000000000FFFFFFFF000100000000000000010000000000000001000000018001E1000000000000FFFFFFFF000100000000000000010000000000000001000000018003E1000000000000FFFFFFFF0001000000000000000100000000000000010000000180CD7F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF000000000000000000010000000000000001000000018023E1000000000000FFFFFFFF000100000000000000010000000000000001000000018022E1000000000000FFFFFFFF000100000000000000010000000000000001000000018025E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802BE1000000000000FFFFFFFF00010000000000000001000000000000000100000001802CE1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001807A8A000000000000FFFFFFFF00010000000000000001000000000000000100000001807B8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180D3B0000000000000FFFFFFFF000100000000000000010000000000000001000000018015B1000000000000FFFFFFFF0001000000000000000100000000000000010000000180F4B0000000000000FFFFFFFF000100000000000000010000000000000001000000018036B1000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FF88000000000000FFFFFFFF0001000000000000000100000000000000010000000180FE88000000000000FFFFFFFF00010000000000000001000000000000000100000001800B81000000000000FFFFFFFF00010000000000000001000000000000000100000001800C81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180F088000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE7F000000000000FFFFFFFF000100000000000000010000000000000001000000018024E1000000000000FFFFFFFF00010000000000000001000000000000000100000001800A81000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001802280000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C488000000000000FFFFFFFF0001000000000000000100000000000000010000000180C988000000000000FFFFFFFF0001000000000000000100000000000000010000000180C788000000000000FFFFFFFF0001000000000000000100000000000000010000000180C888000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180DD88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180FB7F000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 1423 + 2800FFFF01001100434D4643546F6F6C426172427574746F6E00E100000000000000000000000000000000000000000000000100000001000000018001E100000000000001000000000000000000000000000000000100000001000000018003E1000000000000020000000000000000000000000000000001000000010000000180CD7F0000000000000300000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018023E100000000000004000000000000000000000000000000000100000001000000018022E100000000000005000000000000000000000000000000000100000001000000018025E10000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001802BE10000000000000700000000000000000000000000000000010000000100000001802CE10000000000000800000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001807A8A0000000000000900000000000000000000000000000000010000000100000001807B8A0000000000000A00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180D3B00000000000000B000000000000000000000000000000000100000001000000018015B10000000000000C0000000000000000000000000000000001000000010000000180F4B00000000000000D000000000000000000000000000000000100000001000000018036B10000000000000E00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FF880000000000000F0000000000000000000000000000000001000000010000000180FE880000000000001000000000000000000000000000000000010000000100000001800B810000000000001100000000000000000000000000000000010000000100000001800C810000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180F088000000000000130000000000000000000000000000000001000000010000000180EE7F00000000000014000000000000000000000000000000000100000001000000018024E10000000000001500000000000000000000000000000000010000000100000001800A810000000000001600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018022800000000000001700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C488000000000000180000000000000000000000000000000001000000010000000180C988000000000000190000000000000000000000000000000001000000010000000180C7880000000000001A0000000000000000000000000000000001000000010000000180C8880000000000001B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180DD880000000000001C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180FB7F0000000000001D000000000000000000000000000000000100000001000000 + + + + 59399 + Build + + 1000 + 00200000010000001000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F0000000004001C0000000000000000000000000000000001000000010000000180D07F0000000000001D000000000000000000000000000000000100000001000000018030800000000000001E000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6EC7040000000000006A0000000C4261746368204275696C2664000000000000000000000000010000000100000000000000000000000100000004000580C7040000000000006A0000000C4261746368204275696C266400000000000000000000000001000000010000000000000000000000010000000000058046070000000000006B0000000D42617463682052656275696C640000000000000000000000000100000001000000000000000000000001000000000005804707000000000000FFFFFFFF0B426174636820436C65616E0100000000000000000000000100000001000000000000000000000001000000000005809E8A0000000000001F0000000F4261746326682053657475702E2E2E000000000000000000000000010000000100000000000000000000000100000000000180D17F0000000004002000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000004002100000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000FFFF01001900434D4643546F6F6C426172436F6D626F426F78427574746F6EBA0000000000000000000000000000000000000000000000000100000001000000960000000300205000000000144656502053696D756C6174696F6E204D6F64656C96000000000000000100144656502053696D756C6174696F6E204D6F64656C000000000180EB880000000000002200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000230000000000000000000000000000000001000000010000000180B08A000000000000240000000000000000000000000000000001000000010000000180A8010000000000004E00000000000000000000000000000000010000000100000001807202000000000000530000000000000000000000000000000001000000010000000180BE010000000000005000000000000000000000000000000000010000000100000000000000054275696C642F010000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000FFFFFFFF0001000000000000000100000000000000010000000180D07F000000000000FFFFFFFF00010000000000000001000000000000000100000001803080000000000000FFFFFFFF00010000000000000001000000000000000100000001809E8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D17F000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001804C8A000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001806680000000000000FFFFFFFF0001000000000000000100000000000000010000000180EB88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180C07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180B08A000000000000FFFFFFFF0001000000000000000100000000000000010000000180A801000000000000FFFFFFFF00010000000000000001000000000000000100000001807202000000000000FFFFFFFF0001000000000000000100000000000000010000000180BE01000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 583 + 1000FFFF01001100434D4643546F6F6C426172427574746F6ECF7F000000000000000000000000000000000000000000000001000000010000000180D07F00000000000001000000000000000000000000000000000100000001000000018030800000000000000200000000000000000000000000000000010000000100000001809E8A000000000000030000000000000000000000000000000001000000010000000180D17F0000000000000400000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001804C8A0000000000000500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001806680000000000000060000000000000000000000000000000001000000010000000180EB880000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180C07F000000000000080000000000000000000000000000000001000000010000000180B08A000000000000090000000000000000000000000000000001000000010000000180A8010000000000000A000000000000000000000000000000000100000001000000018072020000000000000B0000000000000000000000000000000001000000010000000180BE010000000000000C000000000000000000000000000000000100000001000000 + + + + 59400 + Debug + + 2373 + 00200000000000001900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000002500000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000002600000000000000000000000000000000010000000100000001801D800000000000002700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000002800000000000000000000000000000000010000000100000001801B80000000000000290000000000000000000000000000000001000000010000000180E57F0000000000002A00000000000000000000000000000000010000000100000001801C800000000000002B00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000002C00000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B0000000000002D0000000000000000000000000000000001000000010000000180F07F0000000000002E0000000000000000000000000000000001000000010000000180E8880000000000003700000000000000000000000000000000010000000100000001803B010000000000002F0000000000000000000000000000000001000000010000000180BB8A00000000000030000000000000000000000000000000000100000001000000FFFF01001500434D4643546F6F6C4261724D656E75427574746F6E0E01000000000000310000000D57617463682057696E646F7773000000000000000000000000010000000100000000000000000000000100000003001380D88B00000000000031000000085761746368202631000000000000000000000000010000000100000000000000000000000100000000001380D98B00000000000031000000085761746368202632000000000000000000000000010000000100000000000000000000000100000000001380CE01000000000000FFFFFFFF0C576174636820416E63686F720000000000000000010000000000000001000000000000000000000001000000000013800F01000000000000320000000E4D656D6F72792057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380D28B00000000000032000000094D656D6F7279202631000000000000000000000000010000000100000000000000000000000100000000001380D38B00000000000032000000094D656D6F7279202632000000000000000000000000010000000100000000000000000000000100000000001380D48B00000000000032000000094D656D6F7279202633000000000000000000000000010000000100000000000000000000000100000000001380D58B00000000000032000000094D656D6F72792026340000000000000000000000000100000001000000000000000000000001000000000013801001000000000000330000000E53657269616C2057696E646F77730000000000000000000000000100000001000000000000000000000001000000040013809307000000000000330000000855415254202326310000000000000000000000000100000001000000000000000000000001000000000013809407000000000000330000000855415254202326320000000000000000000000000100000001000000000000000000000001000000000013809507000000000000330000000855415254202326330000000000000000000000000100000001000000000000000000000001000000000013809607000000000000330000001626446562756720287072696E746629205669657765720000000000000000000000000100000001000000000000000000000001000000000013803C010000000000003400000010416E616C797369732057696E646F7773000000000000000000000000010000000100000000000000000000000100000004001380658A000000000000340000000F264C6F67696320416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380DC7F0000000000003E0000001526506572666F726D616E636520416E616C797A6572000000000000000000000000010000000100000000000000000000000100000000001380E788000000000000380000000E26436F646520436F766572616765000000000000000000000000010000000100000000000000000000000100000000001380CD01000000000000FFFFFFFF0F416E616C7973697320416E63686F7200000000000000000100000000000000010000000000000000000000010000000000138053010000000000003F0000000D54726163652057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013805401000000000000FFFFFFFF115472616365204D656E7520416E63686F720000000000000000010000000000000001000000000000000000000001000000000013802901000000000000350000001553797374656D205669657765722057696E646F77730000000000000000000000000100000001000000000000000000000001000000010013804B01000000000000FFFFFFFF1453797374656D2056696577657220416E63686F720000000000000000010000000000000001000000000000000000000001000000000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000013800189000000000000360000000F26546F6F6C626F782057696E646F7700000000000000000000000001000000010000000000000000000000010000000300138044C5000000000000FFFFFFFF0E5570646174652057696E646F77730000000000000000010000000000000001000000000000000000000001000000000013800000000000000400FFFFFFFF000000000000000000010000000000000001000000000000000000000001000000000013805B01000000000000FFFFFFFF12546F6F6C626F78204D656E75416E63686F72000000000000000001000000000000000100000000000000000000000100000000000000000005446562756764020000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC88000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801780000000000000FFFFFFFF00010000000000000001000000000000000100000001801D80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001801A80000000000000FFFFFFFF00010000000000000001000000000000000100000001801B80000000000000FFFFFFFF0001000000000000000100000000000000010000000180E57F000000000000FFFFFFFF00010000000000000001000000000000000100000001801C80000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800089000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF0000000000000000000100000000000000010000000180E48B000000000000FFFFFFFF0001000000000000000100000000000000010000000180F07F000000000000FFFFFFFF0001000000000000000100000000000000010000000180E888000000000000FFFFFFFF00010000000000000001000000000000000100000001803B01000000000000FFFFFFFF0001000000000000000100000000000000010000000180BB8A000000000000FFFFFFFF0001000000000000000100000000000000010000000180D88B000000000000FFFFFFFF0001000000000000000100000000000000010000000180D28B000000000000FFFFFFFF00010000000000000001000000000000000100000001809307000000000000FFFFFFFF0001000000000000000100000000000000010000000180658A000000000000FFFFFFFF0001000000000000000100000000000000010000000180C18A000000000000FFFFFFFF0001000000000000000100000000000000010000000180EE8B000000000000FFFFFFFF00010000000000000001000000000000000100000001800000000000000000FFFFFFFF00000000000000000001000000000000000100000001800189000000000000FFFFFFFF000100000000000000010000000000000001000000 + + + 898 + 1900FFFF01001100434D4643546F6F6C426172427574746F6ECC880000000000000000000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018017800000000000000100000000000000000000000000000000010000000100000001801D800000000000000200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF00000000000000000000000000010000000100000001801A800000000000000300000000000000000000000000000000010000000100000001801B80000000000000040000000000000000000000000000000001000000010000000180E57F0000000000000500000000000000000000000000000000010000000100000001801C800000000000000600000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF000000000000000000000000000100000001000000018000890000000000000700000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180E48B000000000000080000000000000000000000000000000001000000010000000180F07F000000000000090000000000000000000000000000000001000000010000000180E8880000000000000A00000000000000000000000000000000010000000100000001803B010000000000000B0000000000000000000000000000000001000000010000000180BB8A0000000000000C0000000000000000000000000000000001000000010000000180D88B0000000000000D0000000000000000000000000000000001000000010000000180D28B0000000000000E000000000000000000000000000000000100000001000000018093070000000000000F0000000000000000000000000000000001000000010000000180658A000000000000100000000000000000000000000000000001000000010000000180C18A000000000000110000000000000000000000000000000001000000010000000180EE8B0000000000001200000000000000000000000000000000010000000100000001800000000001000000FFFFFFFF0000000000000000000000000001000000010000000180018900000000000013000000000000000000000000000000000100000001000000 + + + + 0 + 1920 + 1080 + + + + + + 1 + 0 + + 100 + 0 + + <1>.\Abstract.txt + 0 + 1 + 1 + 0 + + 0 + + + + +
diff --git a/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvoptx b/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvoptx new file mode 100644 index 000000000..8300b5907 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvoptx @@ -0,0 +1,2576 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + ThreadX_Library_Project + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 0 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 13 + + + + + + + + + + + BIN\UL2V8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FC1000 -FD30000000 + + + + + 0 + + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Source Group + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_allocate.c + tx_block_allocate.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_cleanup.c + tx_block_pool_cleanup.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_create.c + tx_block_pool_create.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_delete.c + tx_block_pool_delete.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_info_get.c + tx_block_pool_info_get.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_initialize.c + tx_block_pool_initialize.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_performance_info_get.c + tx_block_pool_performance_info_get.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c + tx_block_pool_performance_system_info_get.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_pool_prioritize.c + tx_block_pool_prioritize.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_block_release.c + tx_block_release.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_allocate.c + tx_byte_allocate.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_cleanup.c + tx_byte_pool_cleanup.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_create.c + tx_byte_pool_create.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_delete.c + tx_byte_pool_delete.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_info_get.c + tx_byte_pool_info_get.c + 0 + 0 + + + 1 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_initialize.c + tx_byte_pool_initialize.c + 0 + 0 + + + 1 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c + tx_byte_pool_performance_info_get.c + 0 + 0 + + + 1 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c + tx_byte_pool_performance_system_info_get.c + 0 + 0 + + + 1 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_prioritize.c + tx_byte_pool_prioritize.c + 0 + 0 + + + 1 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_pool_search.c + tx_byte_pool_search.c + 0 + 0 + + + 1 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_byte_release.c + tx_byte_release.c + 0 + 0 + + + 1 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_cleanup.c + tx_event_flags_cleanup.c + 0 + 0 + + + 1 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_create.c + tx_event_flags_create.c + 0 + 0 + + + 1 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_delete.c + tx_event_flags_delete.c + 0 + 0 + + + 1 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_get.c + tx_event_flags_get.c + 0 + 0 + + + 1 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_info_get.c + tx_event_flags_info_get.c + 0 + 0 + + + 1 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_initialize.c + tx_event_flags_initialize.c + 0 + 0 + + + 1 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_performance_info_get.c + tx_event_flags_performance_info_get.c + 0 + 0 + + + 1 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c + tx_event_flags_performance_system_info_get.c + 0 + 0 + + + 1 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_set.c + tx_event_flags_set.c + 0 + 0 + + + 1 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_event_flags_set_notify.c + tx_event_flags_set_notify.c + 0 + 0 + + + 1 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_initialize_high_level.c + tx_initialize_high_level.c + 0 + 0 + + + 1 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_initialize_kernel_enter.c + tx_initialize_kernel_enter.c + 0 + 0 + + + 1 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_initialize_kernel_setup.c + tx_initialize_kernel_setup.c + 0 + 0 + + + 1 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_cleanup.c + tx_mutex_cleanup.c + 0 + 0 + + + 1 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_create.c + tx_mutex_create.c + 0 + 0 + + + 1 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_delete.c + tx_mutex_delete.c + 0 + 0 + + + 1 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_get.c + tx_mutex_get.c + 0 + 0 + + + 1 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_info_get.c + tx_mutex_info_get.c + 0 + 0 + + + 1 + 40 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_initialize.c + tx_mutex_initialize.c + 0 + 0 + + + 1 + 41 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_performance_info_get.c + tx_mutex_performance_info_get.c + 0 + 0 + + + 1 + 42 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c + tx_mutex_performance_system_info_get.c + 0 + 0 + + + 1 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_prioritize.c + tx_mutex_prioritize.c + 0 + 0 + + + 1 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_priority_change.c + tx_mutex_priority_change.c + 0 + 0 + + + 1 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_mutex_put.c + tx_mutex_put.c + 0 + 0 + + + 1 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_cleanup.c + tx_queue_cleanup.c + 0 + 0 + + + 1 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_create.c + tx_queue_create.c + 0 + 0 + + + 1 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_delete.c + tx_queue_delete.c + 0 + 0 + + + 1 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_flush.c + tx_queue_flush.c + 0 + 0 + + + 1 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_front_send.c + tx_queue_front_send.c + 0 + 0 + + + 1 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_info_get.c + tx_queue_info_get.c + 0 + 0 + + + 1 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_initialize.c + tx_queue_initialize.c + 0 + 0 + + + 1 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_performance_info_get.c + tx_queue_performance_info_get.c + 0 + 0 + + + 1 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_performance_system_info_get.c + tx_queue_performance_system_info_get.c + 0 + 0 + + + 1 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_prioritize.c + tx_queue_prioritize.c + 0 + 0 + + + 1 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_receive.c + tx_queue_receive.c + 0 + 0 + + + 1 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_send.c + tx_queue_send.c + 0 + 0 + + + 1 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_queue_send_notify.c + tx_queue_send_notify.c + 0 + 0 + + + 1 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_ceiling_put.c + tx_semaphore_ceiling_put.c + 0 + 0 + + + 1 + 60 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_cleanup.c + tx_semaphore_cleanup.c + 0 + 0 + + + 1 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_create.c + tx_semaphore_create.c + 0 + 0 + + + 1 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_delete.c + tx_semaphore_delete.c + 0 + 0 + + + 1 + 63 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_get.c + tx_semaphore_get.c + 0 + 0 + + + 1 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_info_get.c + tx_semaphore_info_get.c + 0 + 0 + + + 1 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_initialize.c + tx_semaphore_initialize.c + 0 + 0 + + + 1 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_performance_info_get.c + tx_semaphore_performance_info_get.c + 0 + 0 + + + 1 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c + tx_semaphore_performance_system_info_get.c + 0 + 0 + + + 1 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_prioritize.c + tx_semaphore_prioritize.c + 0 + 0 + + + 1 + 69 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_put.c + tx_semaphore_put.c + 0 + 0 + + + 1 + 70 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_semaphore_put_notify.c + tx_semaphore_put_notify.c + 0 + 0 + + + 1 + 71 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_create.c + tx_thread_create.c + 0 + 0 + + + 1 + 72 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_delete.c + tx_thread_delete.c + 0 + 0 + + + 1 + 73 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_entry_exit_notify.c + tx_thread_entry_exit_notify.c + 0 + 0 + + + 1 + 74 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_identify.c + tx_thread_identify.c + 0 + 0 + + + 1 + 75 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_info_get.c + tx_thread_info_get.c + 0 + 0 + + + 1 + 76 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_initialize.c + tx_thread_initialize.c + 0 + 0 + + + 1 + 77 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_performance_info_get.c + tx_thread_performance_info_get.c + 0 + 0 + + + 1 + 78 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_performance_system_info_get.c + tx_thread_performance_system_info_get.c + 0 + 0 + + + 1 + 79 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_preemption_change.c + tx_thread_preemption_change.c + 0 + 0 + + + 1 + 80 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_priority_change.c + tx_thread_priority_change.c + 0 + 0 + + + 1 + 81 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_relinquish.c + tx_thread_relinquish.c + 0 + 0 + + + 1 + 82 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_reset.c + tx_thread_reset.c + 0 + 0 + + + 1 + 83 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_resume.c + tx_thread_resume.c + 0 + 0 + + + 1 + 84 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_shell_entry.c + tx_thread_shell_entry.c + 0 + 0 + + + 1 + 85 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_sleep.c + tx_thread_sleep.c + 0 + 0 + + + 1 + 86 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_stack_analyze.c + tx_thread_stack_analyze.c + 0 + 0 + + + 1 + 87 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_suspend.c + tx_thread_suspend.c + 0 + 0 + + + 1 + 88 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_system_preempt_check.c + tx_thread_system_preempt_check.c + 0 + 0 + + + 1 + 89 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_system_resume.c + tx_thread_system_resume.c + 0 + 0 + + + 1 + 90 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_system_suspend.c + tx_thread_system_suspend.c + 0 + 0 + + + 1 + 91 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_terminate.c + tx_thread_terminate.c + 0 + 0 + + + 1 + 92 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_time_slice.c + tx_thread_time_slice.c + 0 + 0 + + + 1 + 93 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_time_slice_change.c + tx_thread_time_slice_change.c + 0 + 0 + + + 1 + 94 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_timeout.c + tx_thread_timeout.c + 0 + 0 + + + 1 + 95 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_wait_abort.c + tx_thread_wait_abort.c + 0 + 0 + + + 1 + 96 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_time_get.c + tx_time_get.c + 0 + 0 + + + 1 + 97 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_time_set.c + tx_time_set.c + 0 + 0 + + + 1 + 98 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_activate.c + tx_timer_activate.c + 0 + 0 + + + 1 + 99 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_change.c + tx_timer_change.c + 0 + 0 + + + 1 + 100 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_create.c + tx_timer_create.c + 0 + 0 + + + 1 + 101 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_deactivate.c + tx_timer_deactivate.c + 0 + 0 + + + 1 + 102 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_delete.c + tx_timer_delete.c + 0 + 0 + + + 1 + 103 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_expiration_process.c + tx_timer_expiration_process.c + 0 + 0 + + + 1 + 104 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_info_get.c + tx_timer_info_get.c + 0 + 0 + + + 1 + 105 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_initialize.c + tx_timer_initialize.c + 0 + 0 + + + 1 + 106 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_performance_info_get.c + tx_timer_performance_info_get.c + 0 + 0 + + + 1 + 107 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_performance_system_info_get.c + tx_timer_performance_system_info_get.c + 0 + 0 + + + 1 + 108 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_system_activate.c + tx_timer_system_activate.c + 0 + 0 + + + 1 + 109 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_system_deactivate.c + tx_timer_system_deactivate.c + 0 + 0 + + + 1 + 110 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_timer_thread_entry.c + tx_timer_thread_entry.c + 0 + 0 + + + 1 + 111 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_disable.c + tx_trace_disable.c + 0 + 0 + + + 1 + 112 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_enable.c + tx_trace_enable.c + 0 + 0 + + + 1 + 113 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_initialize.c + tx_trace_initialize.c + 0 + 0 + + + 1 + 114 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_interrupt_control.c + tx_trace_interrupt_control.c + 0 + 0 + + + 1 + 115 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_isr_enter_insert.c + tx_trace_isr_enter_insert.c + 0 + 0 + + + 1 + 116 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_isr_exit_insert.c + tx_trace_isr_exit_insert.c + 0 + 0 + + + 1 + 117 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_object_register.c + tx_trace_object_register.c + 0 + 0 + + + 1 + 118 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_object_unregister.c + tx_trace_object_unregister.c + 0 + 0 + + + 1 + 119 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_user_event_insert.c + tx_trace_user_event_insert.c + 0 + 0 + + + 1 + 120 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_allocate.c + txe_block_allocate.c + 0 + 0 + + + 1 + 121 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_pool_create.c + txe_block_pool_create.c + 0 + 0 + + + 1 + 122 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_pool_delete.c + txe_block_pool_delete.c + 0 + 0 + + + 1 + 123 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_pool_info_get.c + txe_block_pool_info_get.c + 0 + 0 + + + 1 + 124 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_pool_prioritize.c + txe_block_pool_prioritize.c + 0 + 0 + + + 1 + 125 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_block_release.c + txe_block_release.c + 0 + 0 + + + 1 + 126 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_allocate.c + txe_byte_allocate.c + 0 + 0 + + + 1 + 127 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_pool_create.c + txe_byte_pool_create.c + 0 + 0 + + + 1 + 128 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_pool_delete.c + txe_byte_pool_delete.c + 0 + 0 + + + 1 + 129 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_pool_info_get.c + txe_byte_pool_info_get.c + 0 + 0 + + + 1 + 130 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_pool_prioritize.c + txe_byte_pool_prioritize.c + 0 + 0 + + + 1 + 131 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_byte_release.c + txe_byte_release.c + 0 + 0 + + + 1 + 132 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_create.c + txe_event_flags_create.c + 0 + 0 + + + 1 + 133 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_delete.c + txe_event_flags_delete.c + 0 + 0 + + + 1 + 134 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_get.c + txe_event_flags_get.c + 0 + 0 + + + 1 + 135 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_info_get.c + txe_event_flags_info_get.c + 0 + 0 + + + 1 + 136 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_set.c + txe_event_flags_set.c + 0 + 0 + + + 1 + 137 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_event_flags_set_notify.c + txe_event_flags_set_notify.c + 0 + 0 + + + 1 + 138 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_create.c + txe_mutex_create.c + 0 + 0 + + + 1 + 139 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_delete.c + txe_mutex_delete.c + 0 + 0 + + + 1 + 140 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_get.c + txe_mutex_get.c + 0 + 0 + + + 1 + 141 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_info_get.c + txe_mutex_info_get.c + 0 + 0 + + + 1 + 142 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_prioritize.c + txe_mutex_prioritize.c + 0 + 0 + + + 1 + 143 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_mutex_put.c + txe_mutex_put.c + 0 + 0 + + + 1 + 144 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_create.c + txe_queue_create.c + 0 + 0 + + + 1 + 145 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_delete.c + txe_queue_delete.c + 0 + 0 + + + 1 + 146 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_flush.c + txe_queue_flush.c + 0 + 0 + + + 1 + 147 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_front_send.c + txe_queue_front_send.c + 0 + 0 + + + 1 + 148 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_info_get.c + txe_queue_info_get.c + 0 + 0 + + + 1 + 149 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_prioritize.c + txe_queue_prioritize.c + 0 + 0 + + + 1 + 150 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_receive.c + txe_queue_receive.c + 0 + 0 + + + 1 + 151 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_send.c + txe_queue_send.c + 0 + 0 + + + 1 + 152 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_queue_send_notify.c + txe_queue_send_notify.c + 0 + 0 + + + 1 + 153 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_ceiling_put.c + txe_semaphore_ceiling_put.c + 0 + 0 + + + 1 + 154 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_create.c + txe_semaphore_create.c + 0 + 0 + + + 1 + 155 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_delete.c + txe_semaphore_delete.c + 0 + 0 + + + 1 + 156 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_get.c + txe_semaphore_get.c + 0 + 0 + + + 1 + 157 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_info_get.c + txe_semaphore_info_get.c + 0 + 0 + + + 1 + 158 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_prioritize.c + txe_semaphore_prioritize.c + 0 + 0 + + + 1 + 159 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_put.c + txe_semaphore_put.c + 0 + 0 + + + 1 + 160 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_semaphore_put_notify.c + txe_semaphore_put_notify.c + 0 + 0 + + + 1 + 161 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_create.c + txe_thread_create.c + 0 + 0 + + + 1 + 162 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_delete.c + txe_thread_delete.c + 0 + 0 + + + 1 + 163 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_entry_exit_notify.c + txe_thread_entry_exit_notify.c + 0 + 0 + + + 1 + 164 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_info_get.c + txe_thread_info_get.c + 0 + 0 + + + 1 + 165 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_preemption_change.c + txe_thread_preemption_change.c + 0 + 0 + + + 1 + 166 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_priority_change.c + txe_thread_priority_change.c + 0 + 0 + + + 1 + 167 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_relinquish.c + txe_thread_relinquish.c + 0 + 0 + + + 1 + 168 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_reset.c + txe_thread_reset.c + 0 + 0 + + + 1 + 169 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_resume.c + txe_thread_resume.c + 0 + 0 + + + 1 + 170 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_suspend.c + txe_thread_suspend.c + 0 + 0 + + + 1 + 171 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_terminate.c + txe_thread_terminate.c + 0 + 0 + + + 1 + 172 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_time_slice_change.c + txe_thread_time_slice_change.c + 0 + 0 + + + 1 + 173 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_thread_wait_abort.c + txe_thread_wait_abort.c + 0 + 0 + + + 1 + 174 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_activate.c + txe_timer_activate.c + 0 + 0 + + + 1 + 175 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_change.c + txe_timer_change.c + 0 + 0 + + + 1 + 176 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_create.c + txe_timer_create.c + 0 + 0 + + + 1 + 177 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_deactivate.c + txe_timer_deactivate.c + 0 + 0 + + + 1 + 178 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_delete.c + txe_timer_delete.c + 0 + 0 + + + 1 + 179 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\txe_timer_info_get.c + txe_timer_info_get.c + 0 + 0 + + + 1 + 180 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_buffer_full_notify.c + tx_trace_buffer_full_notify.c + 0 + 0 + + + 1 + 181 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_event_filter.c + tx_trace_event_filter.c + 0 + 0 + + + 1 + 182 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_trace_event_unfilter.c + tx_trace_event_unfilter.c + 0 + 0 + + + 1 + 183 + 1 + 0 + 0 + 0 + ..\src\txe_thread_secure_stack_allocate.c + txe_thread_secure_stack_allocate.c + 0 + 0 + + + 1 + 184 + 1 + 0 + 0 + 0 + ..\src\txe_thread_secure_stack_free.c + txe_thread_secure_stack_free.c + 0 + 0 + + + 1 + 185 + 2 + 0 + 0 + 0 + ..\src\tx_thread_context_restore.S + tx_thread_context_restore.S + 0 + 0 + + + 1 + 186 + 2 + 0 + 0 + 0 + ..\src\tx_thread_context_save.S + tx_thread_context_save.S + 0 + 0 + + + 1 + 187 + 2 + 0 + 0 + 0 + ..\src\tx_thread_interrupt_control.S + tx_thread_interrupt_control.S + 0 + 0 + + + 1 + 188 + 2 + 0 + 0 + 0 + ..\src\tx_thread_interrupt_disable.S + tx_thread_interrupt_disable.S + 0 + 0 + + + 1 + 189 + 2 + 0 + 0 + 0 + ..\src\tx_thread_interrupt_restore.S + tx_thread_interrupt_restore.S + 0 + 0 + + + 1 + 190 + 2 + 0 + 0 + 0 + ..\src\tx_thread_schedule.S + tx_thread_schedule.S + 0 + 0 + + + 1 + 191 + 2 + 0 + 0 + 0 + ..\src\tx_thread_secure_stack_allocate.S + tx_thread_secure_stack_allocate.S + 0 + 0 + + + 1 + 192 + 2 + 0 + 0 + 0 + ..\src\tx_thread_secure_stack_free.S + tx_thread_secure_stack_free.S + 0 + 0 + + + 1 + 193 + 2 + 0 + 0 + 0 + ..\src\tx_thread_stack_build.S + tx_thread_stack_build.S + 0 + 0 + + + 1 + 194 + 2 + 0 + 0 + 0 + ..\src\tx_thread_system_return.S + tx_thread_system_return.S + 0 + 0 + + + 1 + 195 + 2 + 0 + 0 + 0 + ..\src\tx_timer_interrupt.S + tx_timer_interrupt.S + 0 + 0 + + + 1 + 196 + 2 + 0 + 0 + 0 + .\tx_initialize_low_level.S + tx_initialize_low_level.S + 0 + 0 + + + 1 + 197 + 2 + 0 + 0 + 0 + ..\src\tx_thread_secure_stack_initialize.S + tx_thread_secure_stack_initialize.S + 0 + 0 + + + 1 + 198 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_stack_error_handler.c + tx_thread_stack_error_handler.c + 0 + 0 + + + 1 + 199 + 1 + 0 + 0 + 0 + ..\..\..\..\common\src\tx_thread_stack_error_notify.c + tx_thread_stack_error_notify.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvprojx b/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvprojx new file mode 100644 index 000000000..c6c32fa93 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/ThreadX_Library.uvprojx @@ -0,0 +1,1424 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + ThreadX_Library_Project + 0x4 + ARM-ADS + 6180000::V6.18::ARMCLANG + 1 + + + ARMCM55 + ARM + ARM.CMSIS.5.9.0 + http://www.keil.com/pack/ + IRAM(0x30000000,0x00020000) IRAM2(0x20000000,0x00020000) IROM(0x10000000,0x00200000) IROM2(0x00000000,0x00200000) CPUTYPE("Cortex-M55") FPU3(DFPU) DSP TZ MVE(FP) CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD30000000 -FC1000) + 0 + $$Device:ARMCM55$Device\ARM\ARMCM55\Include\ARMCM55.h + + + + + + + + + + + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\ + ThreadX_Library + 0 + 1 + 0 + 1 + 1 + .\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU -MVE + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4100 + + 1 + BIN\UL2V8M.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 0 + 0 + 0 + 1 + 1 + 0 + 0 + 3 + 2 + 0 + 0 + 1 + 1 + 8 + 0 + 1 + 0 + 0 + 4 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x30000000 + 0x20000 + + + 1 + 0x10000000 + 0x200000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x10000000 + 0x200000 + + + 1 + 0x0 + 0x200000 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x30000000 + 0x20000 + + + 0 + 0x20000000 + 0x20000 + + + + + + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 3 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + ..\..\..\..\common\inc, ..\inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + + + + + + + + + + + + Source Group + + + tx_block_allocate.c + 1 + ..\..\..\..\common\src\tx_block_allocate.c + + + tx_block_pool_cleanup.c + 1 + ..\..\..\..\common\src\tx_block_pool_cleanup.c + + + tx_block_pool_create.c + 1 + ..\..\..\..\common\src\tx_block_pool_create.c + + + tx_block_pool_delete.c + 1 + ..\..\..\..\common\src\tx_block_pool_delete.c + + + tx_block_pool_info_get.c + 1 + ..\..\..\..\common\src\tx_block_pool_info_get.c + + + tx_block_pool_initialize.c + 1 + ..\..\..\..\common\src\tx_block_pool_initialize.c + + + tx_block_pool_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_block_pool_performance_info_get.c + + + tx_block_pool_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_block_pool_performance_system_info_get.c + + + tx_block_pool_prioritize.c + 1 + ..\..\..\..\common\src\tx_block_pool_prioritize.c + + + tx_block_release.c + 1 + ..\..\..\..\common\src\tx_block_release.c + + + tx_byte_allocate.c + 1 + ..\..\..\..\common\src\tx_byte_allocate.c + + + tx_byte_pool_cleanup.c + 1 + ..\..\..\..\common\src\tx_byte_pool_cleanup.c + + + tx_byte_pool_create.c + 1 + ..\..\..\..\common\src\tx_byte_pool_create.c + + + tx_byte_pool_delete.c + 1 + ..\..\..\..\common\src\tx_byte_pool_delete.c + + + tx_byte_pool_info_get.c + 1 + ..\..\..\..\common\src\tx_byte_pool_info_get.c + + + tx_byte_pool_initialize.c + 1 + ..\..\..\..\common\src\tx_byte_pool_initialize.c + + + tx_byte_pool_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_byte_pool_performance_info_get.c + + + tx_byte_pool_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_byte_pool_performance_system_info_get.c + + + tx_byte_pool_prioritize.c + 1 + ..\..\..\..\common\src\tx_byte_pool_prioritize.c + + + tx_byte_pool_search.c + 1 + ..\..\..\..\common\src\tx_byte_pool_search.c + + + tx_byte_release.c + 1 + ..\..\..\..\common\src\tx_byte_release.c + + + tx_event_flags_cleanup.c + 1 + ..\..\..\..\common\src\tx_event_flags_cleanup.c + + + tx_event_flags_create.c + 1 + ..\..\..\..\common\src\tx_event_flags_create.c + + + tx_event_flags_delete.c + 1 + ..\..\..\..\common\src\tx_event_flags_delete.c + + + tx_event_flags_get.c + 1 + ..\..\..\..\common\src\tx_event_flags_get.c + + + tx_event_flags_info_get.c + 1 + ..\..\..\..\common\src\tx_event_flags_info_get.c + + + tx_event_flags_initialize.c + 1 + ..\..\..\..\common\src\tx_event_flags_initialize.c + + + tx_event_flags_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_event_flags_performance_info_get.c + + + tx_event_flags_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_event_flags_performance_system_info_get.c + + + tx_event_flags_set.c + 1 + ..\..\..\..\common\src\tx_event_flags_set.c + + + tx_event_flags_set_notify.c + 1 + ..\..\..\..\common\src\tx_event_flags_set_notify.c + + + tx_initialize_high_level.c + 1 + ..\..\..\..\common\src\tx_initialize_high_level.c + + + tx_initialize_kernel_enter.c + 1 + ..\..\..\..\common\src\tx_initialize_kernel_enter.c + + + tx_initialize_kernel_setup.c + 1 + ..\..\..\..\common\src\tx_initialize_kernel_setup.c + + + tx_mutex_cleanup.c + 1 + ..\..\..\..\common\src\tx_mutex_cleanup.c + + + tx_mutex_create.c + 1 + ..\..\..\..\common\src\tx_mutex_create.c + + + tx_mutex_delete.c + 1 + ..\..\..\..\common\src\tx_mutex_delete.c + + + tx_mutex_get.c + 1 + ..\..\..\..\common\src\tx_mutex_get.c + + + tx_mutex_info_get.c + 1 + ..\..\..\..\common\src\tx_mutex_info_get.c + + + tx_mutex_initialize.c + 1 + ..\..\..\..\common\src\tx_mutex_initialize.c + + + tx_mutex_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_mutex_performance_info_get.c + + + tx_mutex_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_mutex_performance_system_info_get.c + + + tx_mutex_prioritize.c + 1 + ..\..\..\..\common\src\tx_mutex_prioritize.c + + + tx_mutex_priority_change.c + 1 + ..\..\..\..\common\src\tx_mutex_priority_change.c + + + tx_mutex_put.c + 1 + ..\..\..\..\common\src\tx_mutex_put.c + + + tx_queue_cleanup.c + 1 + ..\..\..\..\common\src\tx_queue_cleanup.c + + + tx_queue_create.c + 1 + ..\..\..\..\common\src\tx_queue_create.c + + + tx_queue_delete.c + 1 + ..\..\..\..\common\src\tx_queue_delete.c + + + tx_queue_flush.c + 1 + ..\..\..\..\common\src\tx_queue_flush.c + + + tx_queue_front_send.c + 1 + ..\..\..\..\common\src\tx_queue_front_send.c + + + tx_queue_info_get.c + 1 + ..\..\..\..\common\src\tx_queue_info_get.c + + + tx_queue_initialize.c + 1 + ..\..\..\..\common\src\tx_queue_initialize.c + + + tx_queue_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_queue_performance_info_get.c + + + tx_queue_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_queue_performance_system_info_get.c + + + tx_queue_prioritize.c + 1 + ..\..\..\..\common\src\tx_queue_prioritize.c + + + tx_queue_receive.c + 1 + ..\..\..\..\common\src\tx_queue_receive.c + + + tx_queue_send.c + 1 + ..\..\..\..\common\src\tx_queue_send.c + + + tx_queue_send_notify.c + 1 + ..\..\..\..\common\src\tx_queue_send_notify.c + + + tx_semaphore_ceiling_put.c + 1 + ..\..\..\..\common\src\tx_semaphore_ceiling_put.c + + + tx_semaphore_cleanup.c + 1 + ..\..\..\..\common\src\tx_semaphore_cleanup.c + + + tx_semaphore_create.c + 1 + ..\..\..\..\common\src\tx_semaphore_create.c + + + tx_semaphore_delete.c + 1 + ..\..\..\..\common\src\tx_semaphore_delete.c + + + tx_semaphore_get.c + 1 + ..\..\..\..\common\src\tx_semaphore_get.c + + + tx_semaphore_info_get.c + 1 + ..\..\..\..\common\src\tx_semaphore_info_get.c + + + tx_semaphore_initialize.c + 1 + ..\..\..\..\common\src\tx_semaphore_initialize.c + + + tx_semaphore_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_semaphore_performance_info_get.c + + + tx_semaphore_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_semaphore_performance_system_info_get.c + + + tx_semaphore_prioritize.c + 1 + ..\..\..\..\common\src\tx_semaphore_prioritize.c + + + tx_semaphore_put.c + 1 + ..\..\..\..\common\src\tx_semaphore_put.c + + + tx_semaphore_put_notify.c + 1 + ..\..\..\..\common\src\tx_semaphore_put_notify.c + + + tx_thread_create.c + 1 + ..\..\..\..\common\src\tx_thread_create.c + + + tx_thread_delete.c + 1 + ..\..\..\..\common\src\tx_thread_delete.c + + + tx_thread_entry_exit_notify.c + 1 + ..\..\..\..\common\src\tx_thread_entry_exit_notify.c + + + tx_thread_identify.c + 1 + ..\..\..\..\common\src\tx_thread_identify.c + + + tx_thread_info_get.c + 1 + ..\..\..\..\common\src\tx_thread_info_get.c + + + tx_thread_initialize.c + 1 + ..\..\..\..\common\src\tx_thread_initialize.c + + + tx_thread_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_thread_performance_info_get.c + + + tx_thread_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_thread_performance_system_info_get.c + + + tx_thread_preemption_change.c + 1 + ..\..\..\..\common\src\tx_thread_preemption_change.c + + + tx_thread_priority_change.c + 1 + ..\..\..\..\common\src\tx_thread_priority_change.c + + + tx_thread_relinquish.c + 1 + ..\..\..\..\common\src\tx_thread_relinquish.c + + + tx_thread_reset.c + 1 + ..\..\..\..\common\src\tx_thread_reset.c + + + tx_thread_resume.c + 1 + ..\..\..\..\common\src\tx_thread_resume.c + + + tx_thread_shell_entry.c + 1 + ..\..\..\..\common\src\tx_thread_shell_entry.c + + + tx_thread_sleep.c + 1 + ..\..\..\..\common\src\tx_thread_sleep.c + + + tx_thread_stack_analyze.c + 1 + ..\..\..\..\common\src\tx_thread_stack_analyze.c + + + tx_thread_suspend.c + 1 + ..\..\..\..\common\src\tx_thread_suspend.c + + + tx_thread_system_preempt_check.c + 1 + ..\..\..\..\common\src\tx_thread_system_preempt_check.c + + + tx_thread_system_resume.c + 1 + ..\..\..\..\common\src\tx_thread_system_resume.c + + + tx_thread_system_suspend.c + 1 + ..\..\..\..\common\src\tx_thread_system_suspend.c + + + tx_thread_terminate.c + 1 + ..\..\..\..\common\src\tx_thread_terminate.c + + + tx_thread_time_slice.c + 1 + ..\..\..\..\common\src\tx_thread_time_slice.c + + + tx_thread_time_slice_change.c + 1 + ..\..\..\..\common\src\tx_thread_time_slice_change.c + + + tx_thread_timeout.c + 1 + ..\..\..\..\common\src\tx_thread_timeout.c + + + tx_thread_wait_abort.c + 1 + ..\..\..\..\common\src\tx_thread_wait_abort.c + + + tx_time_get.c + 1 + ..\..\..\..\common\src\tx_time_get.c + + + tx_time_set.c + 1 + ..\..\..\..\common\src\tx_time_set.c + + + tx_timer_activate.c + 1 + ..\..\..\..\common\src\tx_timer_activate.c + + + tx_timer_change.c + 1 + ..\..\..\..\common\src\tx_timer_change.c + + + tx_timer_create.c + 1 + ..\..\..\..\common\src\tx_timer_create.c + + + tx_timer_deactivate.c + 1 + ..\..\..\..\common\src\tx_timer_deactivate.c + + + tx_timer_delete.c + 1 + ..\..\..\..\common\src\tx_timer_delete.c + + + tx_timer_expiration_process.c + 1 + ..\..\..\..\common\src\tx_timer_expiration_process.c + + + tx_timer_info_get.c + 1 + ..\..\..\..\common\src\tx_timer_info_get.c + + + tx_timer_initialize.c + 1 + ..\..\..\..\common\src\tx_timer_initialize.c + + + tx_timer_performance_info_get.c + 1 + ..\..\..\..\common\src\tx_timer_performance_info_get.c + + + tx_timer_performance_system_info_get.c + 1 + ..\..\..\..\common\src\tx_timer_performance_system_info_get.c + + + tx_timer_system_activate.c + 1 + ..\..\..\..\common\src\tx_timer_system_activate.c + + + tx_timer_system_deactivate.c + 1 + ..\..\..\..\common\src\tx_timer_system_deactivate.c + + + tx_timer_thread_entry.c + 1 + ..\..\..\..\common\src\tx_timer_thread_entry.c + + + tx_trace_disable.c + 1 + ..\..\..\..\common\src\tx_trace_disable.c + + + tx_trace_enable.c + 1 + ..\..\..\..\common\src\tx_trace_enable.c + + + tx_trace_initialize.c + 1 + ..\..\..\..\common\src\tx_trace_initialize.c + + + tx_trace_interrupt_control.c + 1 + ..\..\..\..\common\src\tx_trace_interrupt_control.c + + + tx_trace_isr_enter_insert.c + 1 + ..\..\..\..\common\src\tx_trace_isr_enter_insert.c + + + tx_trace_isr_exit_insert.c + 1 + ..\..\..\..\common\src\tx_trace_isr_exit_insert.c + + + tx_trace_object_register.c + 1 + ..\..\..\..\common\src\tx_trace_object_register.c + + + tx_trace_object_unregister.c + 1 + ..\..\..\..\common\src\tx_trace_object_unregister.c + + + tx_trace_user_event_insert.c + 1 + ..\..\..\..\common\src\tx_trace_user_event_insert.c + + + txe_block_allocate.c + 1 + ..\..\..\..\common\src\txe_block_allocate.c + + + txe_block_pool_create.c + 1 + ..\..\..\..\common\src\txe_block_pool_create.c + + + txe_block_pool_delete.c + 1 + ..\..\..\..\common\src\txe_block_pool_delete.c + + + txe_block_pool_info_get.c + 1 + ..\..\..\..\common\src\txe_block_pool_info_get.c + + + txe_block_pool_prioritize.c + 1 + ..\..\..\..\common\src\txe_block_pool_prioritize.c + + + txe_block_release.c + 1 + ..\..\..\..\common\src\txe_block_release.c + + + txe_byte_allocate.c + 1 + ..\..\..\..\common\src\txe_byte_allocate.c + + + txe_byte_pool_create.c + 1 + ..\..\..\..\common\src\txe_byte_pool_create.c + + + txe_byte_pool_delete.c + 1 + ..\..\..\..\common\src\txe_byte_pool_delete.c + + + txe_byte_pool_info_get.c + 1 + ..\..\..\..\common\src\txe_byte_pool_info_get.c + + + txe_byte_pool_prioritize.c + 1 + ..\..\..\..\common\src\txe_byte_pool_prioritize.c + + + txe_byte_release.c + 1 + ..\..\..\..\common\src\txe_byte_release.c + + + txe_event_flags_create.c + 1 + ..\..\..\..\common\src\txe_event_flags_create.c + + + txe_event_flags_delete.c + 1 + ..\..\..\..\common\src\txe_event_flags_delete.c + + + txe_event_flags_get.c + 1 + ..\..\..\..\common\src\txe_event_flags_get.c + + + txe_event_flags_info_get.c + 1 + ..\..\..\..\common\src\txe_event_flags_info_get.c + + + txe_event_flags_set.c + 1 + ..\..\..\..\common\src\txe_event_flags_set.c + + + txe_event_flags_set_notify.c + 1 + ..\..\..\..\common\src\txe_event_flags_set_notify.c + + + txe_mutex_create.c + 1 + ..\..\..\..\common\src\txe_mutex_create.c + + + txe_mutex_delete.c + 1 + ..\..\..\..\common\src\txe_mutex_delete.c + + + txe_mutex_get.c + 1 + ..\..\..\..\common\src\txe_mutex_get.c + + + txe_mutex_info_get.c + 1 + ..\..\..\..\common\src\txe_mutex_info_get.c + + + txe_mutex_prioritize.c + 1 + ..\..\..\..\common\src\txe_mutex_prioritize.c + + + txe_mutex_put.c + 1 + ..\..\..\..\common\src\txe_mutex_put.c + + + txe_queue_create.c + 1 + ..\..\..\..\common\src\txe_queue_create.c + + + txe_queue_delete.c + 1 + ..\..\..\..\common\src\txe_queue_delete.c + + + txe_queue_flush.c + 1 + ..\..\..\..\common\src\txe_queue_flush.c + + + txe_queue_front_send.c + 1 + ..\..\..\..\common\src\txe_queue_front_send.c + + + txe_queue_info_get.c + 1 + ..\..\..\..\common\src\txe_queue_info_get.c + + + txe_queue_prioritize.c + 1 + ..\..\..\..\common\src\txe_queue_prioritize.c + + + txe_queue_receive.c + 1 + ..\..\..\..\common\src\txe_queue_receive.c + + + txe_queue_send.c + 1 + ..\..\..\..\common\src\txe_queue_send.c + + + txe_queue_send_notify.c + 1 + ..\..\..\..\common\src\txe_queue_send_notify.c + + + txe_semaphore_ceiling_put.c + 1 + ..\..\..\..\common\src\txe_semaphore_ceiling_put.c + + + txe_semaphore_create.c + 1 + ..\..\..\..\common\src\txe_semaphore_create.c + + + txe_semaphore_delete.c + 1 + ..\..\..\..\common\src\txe_semaphore_delete.c + + + txe_semaphore_get.c + 1 + ..\..\..\..\common\src\txe_semaphore_get.c + + + txe_semaphore_info_get.c + 1 + ..\..\..\..\common\src\txe_semaphore_info_get.c + + + txe_semaphore_prioritize.c + 1 + ..\..\..\..\common\src\txe_semaphore_prioritize.c + + + txe_semaphore_put.c + 1 + ..\..\..\..\common\src\txe_semaphore_put.c + + + txe_semaphore_put_notify.c + 1 + ..\..\..\..\common\src\txe_semaphore_put_notify.c + + + txe_thread_create.c + 1 + ..\..\..\..\common\src\txe_thread_create.c + + + txe_thread_delete.c + 1 + ..\..\..\..\common\src\txe_thread_delete.c + + + txe_thread_entry_exit_notify.c + 1 + ..\..\..\..\common\src\txe_thread_entry_exit_notify.c + + + txe_thread_info_get.c + 1 + ..\..\..\..\common\src\txe_thread_info_get.c + + + txe_thread_preemption_change.c + 1 + ..\..\..\..\common\src\txe_thread_preemption_change.c + + + txe_thread_priority_change.c + 1 + ..\..\..\..\common\src\txe_thread_priority_change.c + + + txe_thread_relinquish.c + 1 + ..\..\..\..\common\src\txe_thread_relinquish.c + + + txe_thread_reset.c + 1 + ..\..\..\..\common\src\txe_thread_reset.c + + + txe_thread_resume.c + 1 + ..\..\..\..\common\src\txe_thread_resume.c + + + txe_thread_suspend.c + 1 + ..\..\..\..\common\src\txe_thread_suspend.c + + + txe_thread_terminate.c + 1 + ..\..\..\..\common\src\txe_thread_terminate.c + + + txe_thread_time_slice_change.c + 1 + ..\..\..\..\common\src\txe_thread_time_slice_change.c + + + txe_thread_wait_abort.c + 1 + ..\..\..\..\common\src\txe_thread_wait_abort.c + + + txe_timer_activate.c + 1 + ..\..\..\..\common\src\txe_timer_activate.c + + + txe_timer_change.c + 1 + ..\..\..\..\common\src\txe_timer_change.c + + + txe_timer_create.c + 1 + ..\..\..\..\common\src\txe_timer_create.c + + + txe_timer_deactivate.c + 1 + ..\..\..\..\common\src\txe_timer_deactivate.c + + + txe_timer_delete.c + 1 + ..\..\..\..\common\src\txe_timer_delete.c + + + txe_timer_info_get.c + 1 + ..\..\..\..\common\src\txe_timer_info_get.c + + + tx_trace_buffer_full_notify.c + 1 + ..\..\..\..\common\src\tx_trace_buffer_full_notify.c + + + tx_trace_event_filter.c + 1 + ..\..\..\..\common\src\tx_trace_event_filter.c + + + tx_trace_event_unfilter.c + 1 + ..\..\..\..\common\src\tx_trace_event_unfilter.c + + + txe_thread_secure_stack_allocate.c + 1 + ..\src\txe_thread_secure_stack_allocate.c + + + txe_thread_secure_stack_free.c + 1 + ..\src\txe_thread_secure_stack_free.c + + + tx_thread_context_restore.S + 2 + ..\src\tx_thread_context_restore.S + + + tx_thread_context_save.S + 2 + ..\src\tx_thread_context_save.S + + + tx_thread_interrupt_control.S + 2 + ..\src\tx_thread_interrupt_control.S + + + tx_thread_interrupt_disable.S + 2 + ..\src\tx_thread_interrupt_disable.S + + + tx_thread_interrupt_restore.S + 2 + ..\src\tx_thread_interrupt_restore.S + + + tx_thread_schedule.S + 2 + ..\src\tx_thread_schedule.S + + + tx_thread_secure_stack_allocate.S + 2 + ..\src\tx_thread_secure_stack_allocate.S + + + tx_thread_secure_stack_free.S + 2 + ..\src\tx_thread_secure_stack_free.S + + + tx_thread_stack_build.S + 2 + ..\src\tx_thread_stack_build.S + + + tx_thread_system_return.S + 2 + ..\src\tx_thread_system_return.S + + + tx_timer_interrupt.S + 2 + ..\src\tx_timer_interrupt.S + + + tx_initialize_low_level.S + 2 + .\tx_initialize_low_level.S + + + tx_thread_secure_stack_initialize.S + 2 + ..\src\tx_thread_secure_stack_initialize.S + + + tx_thread_stack_error_handler.c + 1 + ..\..\..\..\common\src\tx_thread_stack_error_handler.c + + + tx_thread_stack_error_notify.c + 1 + ..\..\..\..\common\src\tx_thread_stack_error_notify.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <Project Info> + 0 + 1 + + + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h new file mode 100644 index 000000000..5bf4c867c --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RTE_DEVICE_H +#define __RTE_DEVICE_H + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] +// Configuration settings for Driver_USART0 in component ::Drivers:USART +#define RTE_USART0 1 + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] +// Configuration settings for Driver_USART1 in component ::Drivers:USART +#define RTE_USART1 1 + +// MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 + +// MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_ISRAM1_MPC 1 + +// MPC (Memory Protection Controller) [Driver_SRAM_MPC] +// Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC +#define RTE_SRAM_MPC 1 + +// MPC (Memory Protection Controller) [Driver_QSPI_MPC] +// Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC +#define RTE_QSPI_MPC 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN0] +// Configuration settings for Driver_PPC_SSE300_MAIN0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP0] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP1] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH0] +// Configuration settings for Driver_PPC_SSE300_PERIPH0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH1] +// Configuration settings for Driver_PPC_SSE300_PERIPH1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP0] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP1] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP2] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP2 1 + +// Flash device emulated by SRAM [Driver_Flash0] +// Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 + +// I2C SBCon [Driver_I2C0] +// Configuration settings for Driver_I2C0 in component ::Drivers:I2C +#define RTE_I2C0 1 + +#endif /* __RTE_DEVICE_H */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h new file mode 100644 index 000000000..bfc348f47 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_DRIVER_CONFIG_H__ +#define __CMSIS_DRIVER_CONFIG_H__ + +#include "system_SSE300MPS3.h" +#include "device_cfg.h" +#include "device_definition.h" +#include "platform_base_address.h" + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h new file mode 100644 index 000000000..2ff3eaa77 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +/** + * \file device_cfg.h + * \brief Configuration file native driver re-targeting + * + * \details This file can be used to add native driver specific macro + * definitions to select which peripherals are available in the build. + * + * This is a default device configuration file with all peripherals enabled. + */ + +/* Secure only peripheral configuration */ + +/* ARM MPS3 IO SCC */ +#define MPS3_IO_S +#define MPS3_IO_DEV MPS3_IO_DEV_S + +/* I2C_SBCon */ +#define I2C0_SBCON_S +#define I2C0_SBCON_DEV I2C0_SBCON_DEV_S + +/* I2S */ +#define MPS3_I2S_S +#define MPS3_I2S_DEV MPS3_I2S_DEV_S + +/* ARM UART Controller PL011 */ +#define UART0_CMSDK_S +#define UART0_CMSDK_DEV UART0_CMSDK_DEV_S +#define UART1_CMSDK_S +#define UART1_CMSDK_DEV UART1_CMSDK_DEV_S + +#define DEFAULT_UART_BAUDRATE 115200U + +/* To be used as CODE and DATA sram */ +#define MPC_ISRAM0_S +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S + +#define MPC_ISRAM1_S +#define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S + +#define MPC_SRAM_S +#define MPC_SRAM_DEV MPC_SRAM_DEV_S + +#define MPC_QSPI_S +#define MPC_QSPI_DEV MPC_QSPI_DEV_S + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S +#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + +#define SYSCOUNTER_READ_ARMV8_M_S +#define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S +/** + * Arbitrary scaling values for test purposes + */ +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u + +/* System timer */ +#define SYSTIMER0_ARMV8_M_S +#define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S +#define SYSTIMER1_ARMV8_M_S +#define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S +#define SYSTIMER2_ARMV8_M_S +#define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S +#define SYSTIMER3_ARMV8_M_S +#define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S + +#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) + +/* CMSDK GPIO driver structures */ +#define GPIO0_CMSDK_S +#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S +#define GPIO1_CMSDK_S +#define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S +#define GPIO2_CMSDK_S +#define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S +#define GPIO3_CMSDK_S +#define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S + +/* System Watchdogs */ +#define SYSWDOG_ARMV8_M_S +#define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S + +/* ARM MPC SIE 300 driver structures */ +#define MPC_VM0_S +#define MPC_VM0_DEV MPC_VM0_DEV_S +#define MPC_VM1_S +#define MPC_VM1_DEV MPC_VM1_DEV_S +#define MPC_SSRAM2_S +#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#define MPC_SSRAM3_S +#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S + +/* ARM PPC driver structures */ +#define PPC_SSE300_MAIN0_S +#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S +#define PPC_SSE300_MAIN_EXP0_S +#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S +#define PPC_SSE300_MAIN_EXP1_S +#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S +#define PPC_SSE300_MAIN_EXP2_S +#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S +#define PPC_SSE300_MAIN_EXP3_S +#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S +#define PPC_SSE300_PERIPH0_S +#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S +#define PPC_SSE300_PERIPH1_S +#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S +#define PPC_SSE300_PERIPH_EXP0_S +#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S +#define PPC_SSE300_PERIPH_EXP1_S +#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S +#define PPC_SSE300_PERIPH_EXP2_S +#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S +#define PPC_SSE300_PERIPH_EXP3_S +#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S + +/* ARM SPI PL022 */ +/* Invalid device stubs are not defined */ +#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */ +#define SPI1_PL022_S +#define SPI1_PL022_DEV SPI1_PL022_DEV_S + + +#endif /* __DEVICE_CFG_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct new file mode 100644 index 000000000..343c63d26 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct @@ -0,0 +1,78 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8.1-m.main -E -xc + +;/* +; * Copyright (c) 2018-2021 Arm Limited. All rights reserved. +; * +; * Licensed under the Apache License, Version 2.0 (the "License"); +; * you may not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * http://www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an "AS IS" BASIS, +; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; */ + +#include "region_defs.h" + +LR_CODE S_CODE_START { + ER_CODE S_CODE_START { + *.o (RESET +First) + .ANY (+RO) + } + + /* + * Place the CMSE Veneers (containing the SG instruction) after the code, in + * a separate 32 bytes aligned region so that the SAU can programmed to just + * set this region as Non-Secure Callable. The maximum size of this + * executable region makes it only used the space left over by the ER_CODE + * region so that you can rely on code+veneer size combined will not exceed + * the S_CODE_SIZE value. We also substract from the available space the + * area used to align this section on 32 bytes boundary (for SAU conf). + */ + ER_CODE_CMSE_VENEER +0 ALIGN 32 { + *(Veneer$$CMSE) + } + /* + * This dummy region ensures that the next one will be aligned on a 32 bytes + * boundary, so that the following region will not be mistakenly configured + * as Non-Secure Callable by the SAU. + */ + ER_CODE_CMSE_VENEER_DUMMY +0 ALIGN 32 EMPTY 0 {} + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + CODE_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(CODE_WATERMARK) <= S_CODE_START + S_CODE_SIZE) + + ER_DATA S_DATA_START { + .ANY (+ZI +RW) + } + + #if HEAP_SIZE > 0 + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SIZE { ; Reserve empty region for heap + } + #endif + + ARM_LIB_STACK +0 ALIGN 32 EMPTY STACK_SIZE { ; Reserve empty region for stack + } + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + SRAM_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(SRAM_WATERMARK) <= S_DATA_START + S_DATA_SIZE) +} diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/partition_CS300.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/partition_CS300.h new file mode 100644 index 000000000..f44e28402 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/partition_CS300.h @@ -0,0 +1,1261 @@ +/**************************************************************************//** + * @file partition_CS300.h + * @brief CMSIS-CORE Initial Setup for Secure / Non-Secure Zones for Armv8.1-M Mainline + * @version V1.0.0 + * @date 20. March 2020 + ******************************************************************************/ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PARTITION_CS300_H +#define PARTITION_CS300_H + +/* +//-------- <<< Use Configuration Wizard in Context Menu >>> ----------------- +*/ + +/* +// Initialize Security Attribution Unit (SAU) CTRL register +*/ +#define SAU_INIT_CTRL 1 + +/* +// Enable SAU +// Value for SAU->CTRL register bit ENABLE +*/ +#define SAU_INIT_CTRL_ENABLE 1 + +/* +// When SAU is disabled +// <0=> All Memory is Secure +// <1=> All Memory is Non-Secure +// Value for SAU->CTRL register bit ALLNS +// When all Memory is Non-Secure (ALLNS is 1), IDAU can override memory map configuration. +*/ +#define SAU_INIT_CTRL_ALLNS 0 + +/* +// +*/ + +/* +// Initialize Security Attribution Unit (SAU) Address Regions +// SAU configuration specifies regions to be one of: +// - Secure and Non-Secure Callable +// - Non-Secure +// Note: All memory regions not configured by SAU are Secure +*/ +#define SAU_REGIONS_MAX 8 /* Max. number of SAU regions */ + +/* +// Initialize SAU Region 0 +// Setup SAU Region 0 memory attributes +*/ +#define SAU_INIT_REGION0 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START0 0x11000000 /* start address of SAU region 0 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END0 0x110003FF /* end address of SAU region 0 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC0 1 +/* +// +*/ + +/* +// Initialize SAU Region 1 +// Setup SAU Region 1 memory attributes +*/ +#define SAU_INIT_REGION1 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START1 0x00080000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END1 0x000FFFFF + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC1 0 +/* +// +*/ + +/* +// Initialize SAU Region 2 +// Setup SAU Region 2 memory attributes +*/ +#define SAU_INIT_REGION2 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START2 0x20080000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END2 0x200FFFFF + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC2 0 +/* +// +*/ + +/* +// Initialize SAU Region 3 +// Setup SAU Region 3 memory attributes +*/ +#define SAU_INIT_REGION3 1 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START3 0x40000000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END3 0x42000000 + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC3 0 +/* +// +*/ + +/* +// Initialize SAU Region 4 +// Setup SAU Region 4 memory attributes +*/ +#define SAU_INIT_REGION4 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START4 0x00000000 /* start address of SAU region 4 */ + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END4 0x00000000 /* end address of SAU region 4 */ + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC4 0 +/* +// +*/ + +/* +// Initialize SAU Region 5 +// Setup SAU Region 5 memory attributes +*/ +#define SAU_INIT_REGION5 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START5 0x00000000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END5 0x00000000 + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC5 0 +/* +// +*/ + +/* +// Initialize SAU Region 6 +// Setup SAU Region 6 memory attributes +*/ +#define SAU_INIT_REGION6 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START6 0x00000000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END6 0x00000000 + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC6 0 +/* +// +*/ + +/* +// Initialize SAU Region 7 +// Setup SAU Region 7 memory attributes +*/ +#define SAU_INIT_REGION7 0 + +/* +// Start Address <0-0xFFFFFFE0> +*/ +#define SAU_INIT_START7 0x00000000 + +/* +// End Address <0x1F-0xFFFFFFFF> +*/ +#define SAU_INIT_END7 0x00000000 + +/* +// Region is +// <0=>Non-Secure +// <1=>Secure, Non-Secure Callable +*/ +#define SAU_INIT_NSC7 0 +/* +// +*/ + +/* +// +*/ + +/* +// Setup behaviour of Sleep and Exception Handling +*/ +#define SCB_CSR_AIRCR_INIT 1 + +/* +// Deep Sleep can be enabled by +// <0=>Secure and Non-Secure state +// <1=>Secure state only +// Value for SCB->CSR register bit DEEPSLEEPS +*/ +#define SCB_CSR_DEEPSLEEPS_VAL 1 + +/* +// System reset request accessible from +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for SCB->AIRCR register bit SYSRESETREQS +*/ +#define SCB_AIRCR_SYSRESETREQS_VAL 1 + +/* +// Priority of Non-Secure exceptions is +// <0=> Not altered +// <1=> Lowered to 0x80-0xFF +// Value for SCB->AIRCR register bit PRIS +*/ +#define SCB_AIRCR_PRIS_VAL 1 + +/* +// BusFault, HardFault, and NMI target +// <0=> Secure state +// <1=> Non-Secure state +// Value for SCB->AIRCR register bit BFHFNMINS +*/ +#define SCB_AIRCR_BFHFNMINS_VAL 0 + +/* +// +*/ + +/* +// Setup behaviour of Floating Point and Vector Unit (FPU/MVE) +*/ +#define TZ_FPU_NS_USAGE 1 + +/* +// Floating Point and Vector Unit usage +// <0=> Secure state only +// <3=> Secure and Non-Secure state +// Value for SCB->NSACR register bits CP10, CP11 +*/ +#define SCB_NSACR_CP10_11_VAL 3 + +/* +// Treat floating-point registers as Secure +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit TS +*/ +#define FPU_FPCCR_TS_VAL 0 + +/* +// Clear on return (CLRONRET) accessibility +// <0=> Secure and Non-Secure state +// <1=> Secure state only +// Value for FPU->FPCCR register bit CLRONRETS +*/ +#define FPU_FPCCR_CLRONRETS_VAL 0 + +/* +// Clear floating-point caller saved registers on exception return +// <0=> Disabled +// <1=> Enabled +// Value for FPU->FPCCR register bit CLRONRET +*/ +#define FPU_FPCCR_CLRONRET_VAL 1 + +/* +// +*/ + +/* +// Setup Interrupt Target +*/ + +/* +// Initialize ITNS 0 (Interrupts 0..31) +*/ +#define NVIC_INIT_ITNS0 1 + +/* +// Interrupts 0..31 +// Interrupt 0 <0=> Secure state <1=> Non-Secure state +// Interrupt 1 <0=> Secure state <1=> Non-Secure state +// Interrupt 2 <0=> Secure state <1=> Non-Secure state +// Interrupt 3 <0=> Secure state <1=> Non-Secure state +// Interrupt 4 <0=> Secure state <1=> Non-Secure state +// Interrupt 5 <0=> Secure state <1=> Non-Secure state +// Interrupt 6 <0=> Secure state <1=> Non-Secure state +// Interrupt 7 <0=> Secure state <1=> Non-Secure state +// Interrupt 8 <0=> Secure state <1=> Non-Secure state +// Interrupt 9 <0=> Secure state <1=> Non-Secure state +// Interrupt 10 <0=> Secure state <1=> Non-Secure state +// Interrupt 11 <0=> Secure state <1=> Non-Secure state +// Interrupt 12 <0=> Secure state <1=> Non-Secure state +// Interrupt 13 <0=> Secure state <1=> Non-Secure state +// Interrupt 14 <0=> Secure state <1=> Non-Secure state +// Interrupt 15 <0=> Secure state <1=> Non-Secure state +// Interrupt 16 <0=> Secure state <1=> Non-Secure state +// Interrupt 17 <0=> Secure state <1=> Non-Secure state +// Interrupt 18 <0=> Secure state <1=> Non-Secure state +// Interrupt 19 <0=> Secure state <1=> Non-Secure state +// Interrupt 20 <0=> Secure state <1=> Non-Secure state +// Interrupt 21 <0=> Secure state <1=> Non-Secure state +// Interrupt 22 <0=> Secure state <1=> Non-Secure state +// Interrupt 23 <0=> Secure state <1=> Non-Secure state +// Interrupt 24 <0=> Secure state <1=> Non-Secure state +// Interrupt 25 <0=> Secure state <1=> Non-Secure state +// Interrupt 26 <0=> Secure state <1=> Non-Secure state +// Interrupt 27 <0=> Secure state <1=> Non-Secure state +// Interrupt 28 <0=> Secure state <1=> Non-Secure state +// Interrupt 29 <0=> Secure state <1=> Non-Secure state +// Interrupt 30 <0=> Secure state <1=> Non-Secure state +// Interrupt 31 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS0_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 1 (Interrupts 32..63) +*/ +#define NVIC_INIT_ITNS1 1 + +/* +// Interrupts 32..63 +// Interrupt 32 <0=> Secure state <1=> Non-Secure state +// Interrupt 33 <0=> Secure state <1=> Non-Secure state +// Interrupt 34 <0=> Secure state <1=> Non-Secure state +// Interrupt 35 <0=> Secure state <1=> Non-Secure state +// Interrupt 36 <0=> Secure state <1=> Non-Secure state +// Interrupt 37 <0=> Secure state <1=> Non-Secure state +// Interrupt 38 <0=> Secure state <1=> Non-Secure state +// Interrupt 39 <0=> Secure state <1=> Non-Secure state +// Interrupt 40 <0=> Secure state <1=> Non-Secure state +// Interrupt 41 <0=> Secure state <1=> Non-Secure state +// Interrupt 42 <0=> Secure state <1=> Non-Secure state +// Interrupt 43 <0=> Secure state <1=> Non-Secure state +// Interrupt 44 <0=> Secure state <1=> Non-Secure state +// Interrupt 45 <0=> Secure state <1=> Non-Secure state +// Interrupt 46 <0=> Secure state <1=> Non-Secure state +// Interrupt 47 <0=> Secure state <1=> Non-Secure state +// Interrupt 48 <0=> Secure state <1=> Non-Secure state +// Interrupt 49 <0=> Secure state <1=> Non-Secure state +// Interrupt 50 <0=> Secure state <1=> Non-Secure state +// Interrupt 51 <0=> Secure state <1=> Non-Secure state +// Interrupt 52 <0=> Secure state <1=> Non-Secure state +// Interrupt 53 <0=> Secure state <1=> Non-Secure state +// Interrupt 54 <0=> Secure state <1=> Non-Secure state +// Interrupt 55 <0=> Secure state <1=> Non-Secure state +// Interrupt 56 <0=> Secure state <1=> Non-Secure state +// Interrupt 57 <0=> Secure state <1=> Non-Secure state +// Interrupt 58 <0=> Secure state <1=> Non-Secure state +// Interrupt 59 <0=> Secure state <1=> Non-Secure state +// Interrupt 60 <0=> Secure state <1=> Non-Secure state +// Interrupt 61 <0=> Secure state <1=> Non-Secure state +// Interrupt 62 <0=> Secure state <1=> Non-Secure state +// Interrupt 63 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS1_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 2 (Interrupts 64..95) +*/ +#define NVIC_INIT_ITNS2 0 + +/* +// Interrupts 64..95 +// Interrupt 64 <0=> Secure state <1=> Non-Secure state +// Interrupt 65 <0=> Secure state <1=> Non-Secure state +// Interrupt 66 <0=> Secure state <1=> Non-Secure state +// Interrupt 67 <0=> Secure state <1=> Non-Secure state +// Interrupt 68 <0=> Secure state <1=> Non-Secure state +// Interrupt 69 <0=> Secure state <1=> Non-Secure state +// Interrupt 70 <0=> Secure state <1=> Non-Secure state +// Interrupt 71 <0=> Secure state <1=> Non-Secure state +// Interrupt 72 <0=> Secure state <1=> Non-Secure state +// Interrupt 73 <0=> Secure state <1=> Non-Secure state +// Interrupt 74 <0=> Secure state <1=> Non-Secure state +// Interrupt 75 <0=> Secure state <1=> Non-Secure state +// Interrupt 76 <0=> Secure state <1=> Non-Secure state +// Interrupt 77 <0=> Secure state <1=> Non-Secure state +// Interrupt 78 <0=> Secure state <1=> Non-Secure state +// Interrupt 79 <0=> Secure state <1=> Non-Secure state +// Interrupt 80 <0=> Secure state <1=> Non-Secure state +// Interrupt 81 <0=> Secure state <1=> Non-Secure state +// Interrupt 82 <0=> Secure state <1=> Non-Secure state +// Interrupt 83 <0=> Secure state <1=> Non-Secure state +// Interrupt 84 <0=> Secure state <1=> Non-Secure state +// Interrupt 85 <0=> Secure state <1=> Non-Secure state +// Interrupt 86 <0=> Secure state <1=> Non-Secure state +// Interrupt 87 <0=> Secure state <1=> Non-Secure state +// Interrupt 88 <0=> Secure state <1=> Non-Secure state +// Interrupt 89 <0=> Secure state <1=> Non-Secure state +// Interrupt 90 <0=> Secure state <1=> Non-Secure state +// Interrupt 91 <0=> Secure state <1=> Non-Secure state +// Interrupt 92 <0=> Secure state <1=> Non-Secure state +// Interrupt 93 <0=> Secure state <1=> Non-Secure state +// Interrupt 94 <0=> Secure state <1=> Non-Secure state +// Interrupt 95 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS2_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 3 (Interrupts 96..127) +*/ +#define NVIC_INIT_ITNS3 0 + +/* +// Interrupts 96..127 +// Interrupt 96 <0=> Secure state <1=> Non-Secure state +// Interrupt 97 <0=> Secure state <1=> Non-Secure state +// Interrupt 98 <0=> Secure state <1=> Non-Secure state +// Interrupt 99 <0=> Secure state <1=> Non-Secure state +// Interrupt 100 <0=> Secure state <1=> Non-Secure state +// Interrupt 101 <0=> Secure state <1=> Non-Secure state +// Interrupt 102 <0=> Secure state <1=> Non-Secure state +// Interrupt 103 <0=> Secure state <1=> Non-Secure state +// Interrupt 104 <0=> Secure state <1=> Non-Secure state +// Interrupt 105 <0=> Secure state <1=> Non-Secure state +// Interrupt 106 <0=> Secure state <1=> Non-Secure state +// Interrupt 107 <0=> Secure state <1=> Non-Secure state +// Interrupt 108 <0=> Secure state <1=> Non-Secure state +// Interrupt 109 <0=> Secure state <1=> Non-Secure state +// Interrupt 110 <0=> Secure state <1=> Non-Secure state +// Interrupt 111 <0=> Secure state <1=> Non-Secure state +// Interrupt 112 <0=> Secure state <1=> Non-Secure state +// Interrupt 113 <0=> Secure state <1=> Non-Secure state +// Interrupt 114 <0=> Secure state <1=> Non-Secure state +// Interrupt 115 <0=> Secure state <1=> Non-Secure state +// Interrupt 116 <0=> Secure state <1=> Non-Secure state +// Interrupt 117 <0=> Secure state <1=> Non-Secure state +// Interrupt 118 <0=> Secure state <1=> Non-Secure state +// Interrupt 119 <0=> Secure state <1=> Non-Secure state +// Interrupt 120 <0=> Secure state <1=> Non-Secure state +// Interrupt 121 <0=> Secure state <1=> Non-Secure state +// Interrupt 122 <0=> Secure state <1=> Non-Secure state +// Interrupt 123 <0=> Secure state <1=> Non-Secure state +// Interrupt 124 <0=> Secure state <1=> Non-Secure state +// Interrupt 125 <0=> Secure state <1=> Non-Secure state +// Interrupt 126 <0=> Secure state <1=> Non-Secure state +// Interrupt 127 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS3_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 4 (Interrupts 128..159) +*/ +#define NVIC_INIT_ITNS4 0 + +/* +// Interrupts 128..159 +// Interrupt 128 <0=> Secure state <1=> Non-Secure state +// Interrupt 129 <0=> Secure state <1=> Non-Secure state +// Interrupt 130 <0=> Secure state <1=> Non-Secure state +// Interrupt 131 <0=> Secure state <1=> Non-Secure state +// Interrupt 132 <0=> Secure state <1=> Non-Secure state +// Interrupt 133 <0=> Secure state <1=> Non-Secure state +// Interrupt 134 <0=> Secure state <1=> Non-Secure state +// Interrupt 135 <0=> Secure state <1=> Non-Secure state +// Interrupt 136 <0=> Secure state <1=> Non-Secure state +// Interrupt 137 <0=> Secure state <1=> Non-Secure state +// Interrupt 138 <0=> Secure state <1=> Non-Secure state +// Interrupt 139 <0=> Secure state <1=> Non-Secure state +// Interrupt 140 <0=> Secure state <1=> Non-Secure state +// Interrupt 141 <0=> Secure state <1=> Non-Secure state +// Interrupt 142 <0=> Secure state <1=> Non-Secure state +// Interrupt 143 <0=> Secure state <1=> Non-Secure state +// Interrupt 144 <0=> Secure state <1=> Non-Secure state +// Interrupt 145 <0=> Secure state <1=> Non-Secure state +// Interrupt 146 <0=> Secure state <1=> Non-Secure state +// Interrupt 147 <0=> Secure state <1=> Non-Secure state +// Interrupt 148 <0=> Secure state <1=> Non-Secure state +// Interrupt 149 <0=> Secure state <1=> Non-Secure state +// Interrupt 150 <0=> Secure state <1=> Non-Secure state +// Interrupt 151 <0=> Secure state <1=> Non-Secure state +// Interrupt 152 <0=> Secure state <1=> Non-Secure state +// Interrupt 153 <0=> Secure state <1=> Non-Secure state +// Interrupt 154 <0=> Secure state <1=> Non-Secure state +// Interrupt 155 <0=> Secure state <1=> Non-Secure state +// Interrupt 156 <0=> Secure state <1=> Non-Secure state +// Interrupt 157 <0=> Secure state <1=> Non-Secure state +// Interrupt 158 <0=> Secure state <1=> Non-Secure state +// Interrupt 159 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS4_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 5 (Interrupts 160..191) +*/ +#define NVIC_INIT_ITNS5 0 + +/* +// Interrupts 160..191 +// Interrupt 160 <0=> Secure state <1=> Non-Secure state +// Interrupt 161 <0=> Secure state <1=> Non-Secure state +// Interrupt 162 <0=> Secure state <1=> Non-Secure state +// Interrupt 163 <0=> Secure state <1=> Non-Secure state +// Interrupt 164 <0=> Secure state <1=> Non-Secure state +// Interrupt 165 <0=> Secure state <1=> Non-Secure state +// Interrupt 166 <0=> Secure state <1=> Non-Secure state +// Interrupt 167 <0=> Secure state <1=> Non-Secure state +// Interrupt 168 <0=> Secure state <1=> Non-Secure state +// Interrupt 169 <0=> Secure state <1=> Non-Secure state +// Interrupt 170 <0=> Secure state <1=> Non-Secure state +// Interrupt 171 <0=> Secure state <1=> Non-Secure state +// Interrupt 172 <0=> Secure state <1=> Non-Secure state +// Interrupt 173 <0=> Secure state <1=> Non-Secure state +// Interrupt 174 <0=> Secure state <1=> Non-Secure state +// Interrupt 175 <0=> Secure state <1=> Non-Secure state +// Interrupt 176 <0=> Secure state <1=> Non-Secure state +// Interrupt 177 <0=> Secure state <1=> Non-Secure state +// Interrupt 178 <0=> Secure state <1=> Non-Secure state +// Interrupt 179 <0=> Secure state <1=> Non-Secure state +// Interrupt 180 <0=> Secure state <1=> Non-Secure state +// Interrupt 181 <0=> Secure state <1=> Non-Secure state +// Interrupt 182 <0=> Secure state <1=> Non-Secure state +// Interrupt 183 <0=> Secure state <1=> Non-Secure state +// Interrupt 184 <0=> Secure state <1=> Non-Secure state +// Interrupt 185 <0=> Secure state <1=> Non-Secure state +// Interrupt 186 <0=> Secure state <1=> Non-Secure state +// Interrupt 187 <0=> Secure state <1=> Non-Secure state +// Interrupt 188 <0=> Secure state <1=> Non-Secure state +// Interrupt 189 <0=> Secure state <1=> Non-Secure state +// Interrupt 190 <0=> Secure state <1=> Non-Secure state +// Interrupt 191 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS5_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 6 (Interrupts 192..223) +*/ +#define NVIC_INIT_ITNS6 0 + +/* +// Interrupts 192..223 +// Interrupt 192 <0=> Secure state <1=> Non-Secure state +// Interrupt 193 <0=> Secure state <1=> Non-Secure state +// Interrupt 194 <0=> Secure state <1=> Non-Secure state +// Interrupt 195 <0=> Secure state <1=> Non-Secure state +// Interrupt 196 <0=> Secure state <1=> Non-Secure state +// Interrupt 197 <0=> Secure state <1=> Non-Secure state +// Interrupt 198 <0=> Secure state <1=> Non-Secure state +// Interrupt 199 <0=> Secure state <1=> Non-Secure state +// Interrupt 200 <0=> Secure state <1=> Non-Secure state +// Interrupt 201 <0=> Secure state <1=> Non-Secure state +// Interrupt 202 <0=> Secure state <1=> Non-Secure state +// Interrupt 203 <0=> Secure state <1=> Non-Secure state +// Interrupt 204 <0=> Secure state <1=> Non-Secure state +// Interrupt 205 <0=> Secure state <1=> Non-Secure state +// Interrupt 206 <0=> Secure state <1=> Non-Secure state +// Interrupt 207 <0=> Secure state <1=> Non-Secure state +// Interrupt 208 <0=> Secure state <1=> Non-Secure state +// Interrupt 209 <0=> Secure state <1=> Non-Secure state +// Interrupt 210 <0=> Secure state <1=> Non-Secure state +// Interrupt 211 <0=> Secure state <1=> Non-Secure state +// Interrupt 212 <0=> Secure state <1=> Non-Secure state +// Interrupt 213 <0=> Secure state <1=> Non-Secure state +// Interrupt 214 <0=> Secure state <1=> Non-Secure state +// Interrupt 215 <0=> Secure state <1=> Non-Secure state +// Interrupt 216 <0=> Secure state <1=> Non-Secure state +// Interrupt 217 <0=> Secure state <1=> Non-Secure state +// Interrupt 218 <0=> Secure state <1=> Non-Secure state +// Interrupt 219 <0=> Secure state <1=> Non-Secure state +// Interrupt 220 <0=> Secure state <1=> Non-Secure state +// Interrupt 221 <0=> Secure state <1=> Non-Secure state +// Interrupt 222 <0=> Secure state <1=> Non-Secure state +// Interrupt 223 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS6_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 7 (Interrupts 224..255) +*/ +#define NVIC_INIT_ITNS7 0 + +/* +// Interrupts 224..255 +// Interrupt 224 <0=> Secure state <1=> Non-Secure state +// Interrupt 225 <0=> Secure state <1=> Non-Secure state +// Interrupt 226 <0=> Secure state <1=> Non-Secure state +// Interrupt 227 <0=> Secure state <1=> Non-Secure state +// Interrupt 228 <0=> Secure state <1=> Non-Secure state +// Interrupt 229 <0=> Secure state <1=> Non-Secure state +// Interrupt 230 <0=> Secure state <1=> Non-Secure state +// Interrupt 231 <0=> Secure state <1=> Non-Secure state +// Interrupt 232 <0=> Secure state <1=> Non-Secure state +// Interrupt 233 <0=> Secure state <1=> Non-Secure state +// Interrupt 234 <0=> Secure state <1=> Non-Secure state +// Interrupt 235 <0=> Secure state <1=> Non-Secure state +// Interrupt 236 <0=> Secure state <1=> Non-Secure state +// Interrupt 237 <0=> Secure state <1=> Non-Secure state +// Interrupt 238 <0=> Secure state <1=> Non-Secure state +// Interrupt 239 <0=> Secure state <1=> Non-Secure state +// Interrupt 240 <0=> Secure state <1=> Non-Secure state +// Interrupt 241 <0=> Secure state <1=> Non-Secure state +// Interrupt 242 <0=> Secure state <1=> Non-Secure state +// Interrupt 243 <0=> Secure state <1=> Non-Secure state +// Interrupt 244 <0=> Secure state <1=> Non-Secure state +// Interrupt 245 <0=> Secure state <1=> Non-Secure state +// Interrupt 246 <0=> Secure state <1=> Non-Secure state +// Interrupt 247 <0=> Secure state <1=> Non-Secure state +// Interrupt 248 <0=> Secure state <1=> Non-Secure state +// Interrupt 249 <0=> Secure state <1=> Non-Secure state +// Interrupt 250 <0=> Secure state <1=> Non-Secure state +// Interrupt 251 <0=> Secure state <1=> Non-Secure state +// Interrupt 252 <0=> Secure state <1=> Non-Secure state +// Interrupt 253 <0=> Secure state <1=> Non-Secure state +// Interrupt 254 <0=> Secure state <1=> Non-Secure state +// Interrupt 255 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS7_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 8 (Interrupts 256..287) +*/ +#define NVIC_INIT_ITNS8 0 + +/* +// Interrupts 256..287 +// Interrupt 256 <0=> Secure state <1=> Non-Secure state +// Interrupt 257 <0=> Secure state <1=> Non-Secure state +// Interrupt 258 <0=> Secure state <1=> Non-Secure state +// Interrupt 259 <0=> Secure state <1=> Non-Secure state +// Interrupt 260 <0=> Secure state <1=> Non-Secure state +// Interrupt 261 <0=> Secure state <1=> Non-Secure state +// Interrupt 262 <0=> Secure state <1=> Non-Secure state +// Interrupt 263 <0=> Secure state <1=> Non-Secure state +// Interrupt 264 <0=> Secure state <1=> Non-Secure state +// Interrupt 265 <0=> Secure state <1=> Non-Secure state +// Interrupt 266 <0=> Secure state <1=> Non-Secure state +// Interrupt 267 <0=> Secure state <1=> Non-Secure state +// Interrupt 268 <0=> Secure state <1=> Non-Secure state +// Interrupt 269 <0=> Secure state <1=> Non-Secure state +// Interrupt 270 <0=> Secure state <1=> Non-Secure state +// Interrupt 271 <0=> Secure state <1=> Non-Secure state +// Interrupt 272 <0=> Secure state <1=> Non-Secure state +// Interrupt 273 <0=> Secure state <1=> Non-Secure state +// Interrupt 274 <0=> Secure state <1=> Non-Secure state +// Interrupt 275 <0=> Secure state <1=> Non-Secure state +// Interrupt 276 <0=> Secure state <1=> Non-Secure state +// Interrupt 277 <0=> Secure state <1=> Non-Secure state +// Interrupt 278 <0=> Secure state <1=> Non-Secure state +// Interrupt 279 <0=> Secure state <1=> Non-Secure state +// Interrupt 280 <0=> Secure state <1=> Non-Secure state +// Interrupt 281 <0=> Secure state <1=> Non-Secure state +// Interrupt 282 <0=> Secure state <1=> Non-Secure state +// Interrupt 283 <0=> Secure state <1=> Non-Secure state +// Interrupt 284 <0=> Secure state <1=> Non-Secure state +// Interrupt 285 <0=> Secure state <1=> Non-Secure state +// Interrupt 286 <0=> Secure state <1=> Non-Secure state +// Interrupt 287 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS8_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 9 (Interrupts 288..319) +*/ +#define NVIC_INIT_ITNS9 0 + +/* +// Interrupts 288..319 +// Interrupt 288 <0=> Secure state <1=> Non-Secure state +// Interrupt 289 <0=> Secure state <1=> Non-Secure state +// Interrupt 290 <0=> Secure state <1=> Non-Secure state +// Interrupt 291 <0=> Secure state <1=> Non-Secure state +// Interrupt 292 <0=> Secure state <1=> Non-Secure state +// Interrupt 293 <0=> Secure state <1=> Non-Secure state +// Interrupt 294 <0=> Secure state <1=> Non-Secure state +// Interrupt 295 <0=> Secure state <1=> Non-Secure state +// Interrupt 296 <0=> Secure state <1=> Non-Secure state +// Interrupt 297 <0=> Secure state <1=> Non-Secure state +// Interrupt 298 <0=> Secure state <1=> Non-Secure state +// Interrupt 299 <0=> Secure state <1=> Non-Secure state +// Interrupt 300 <0=> Secure state <1=> Non-Secure state +// Interrupt 301 <0=> Secure state <1=> Non-Secure state +// Interrupt 302 <0=> Secure state <1=> Non-Secure state +// Interrupt 303 <0=> Secure state <1=> Non-Secure state +// Interrupt 304 <0=> Secure state <1=> Non-Secure state +// Interrupt 305 <0=> Secure state <1=> Non-Secure state +// Interrupt 306 <0=> Secure state <1=> Non-Secure state +// Interrupt 307 <0=> Secure state <1=> Non-Secure state +// Interrupt 308 <0=> Secure state <1=> Non-Secure state +// Interrupt 309 <0=> Secure state <1=> Non-Secure state +// Interrupt 310 <0=> Secure state <1=> Non-Secure state +// Interrupt 311 <0=> Secure state <1=> Non-Secure state +// Interrupt 312 <0=> Secure state <1=> Non-Secure state +// Interrupt 313 <0=> Secure state <1=> Non-Secure state +// Interrupt 314 <0=> Secure state <1=> Non-Secure state +// Interrupt 315 <0=> Secure state <1=> Non-Secure state +// Interrupt 316 <0=> Secure state <1=> Non-Secure state +// Interrupt 317 <0=> Secure state <1=> Non-Secure state +// Interrupt 318 <0=> Secure state <1=> Non-Secure state +// Interrupt 319 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS9_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 10 (Interrupts 320..351) +*/ +#define NVIC_INIT_ITNS10 0 + +/* +// Interrupts 320..351 +// Interrupt 320 <0=> Secure state <1=> Non-Secure state +// Interrupt 321 <0=> Secure state <1=> Non-Secure state +// Interrupt 322 <0=> Secure state <1=> Non-Secure state +// Interrupt 323 <0=> Secure state <1=> Non-Secure state +// Interrupt 324 <0=> Secure state <1=> Non-Secure state +// Interrupt 325 <0=> Secure state <1=> Non-Secure state +// Interrupt 326 <0=> Secure state <1=> Non-Secure state +// Interrupt 327 <0=> Secure state <1=> Non-Secure state +// Interrupt 328 <0=> Secure state <1=> Non-Secure state +// Interrupt 329 <0=> Secure state <1=> Non-Secure state +// Interrupt 330 <0=> Secure state <1=> Non-Secure state +// Interrupt 331 <0=> Secure state <1=> Non-Secure state +// Interrupt 332 <0=> Secure state <1=> Non-Secure state +// Interrupt 333 <0=> Secure state <1=> Non-Secure state +// Interrupt 334 <0=> Secure state <1=> Non-Secure state +// Interrupt 335 <0=> Secure state <1=> Non-Secure state +// Interrupt 336 <0=> Secure state <1=> Non-Secure state +// Interrupt 337 <0=> Secure state <1=> Non-Secure state +// Interrupt 338 <0=> Secure state <1=> Non-Secure state +// Interrupt 339 <0=> Secure state <1=> Non-Secure state +// Interrupt 340 <0=> Secure state <1=> Non-Secure state +// Interrupt 341 <0=> Secure state <1=> Non-Secure state +// Interrupt 342 <0=> Secure state <1=> Non-Secure state +// Interrupt 343 <0=> Secure state <1=> Non-Secure state +// Interrupt 344 <0=> Secure state <1=> Non-Secure state +// Interrupt 345 <0=> Secure state <1=> Non-Secure state +// Interrupt 346 <0=> Secure state <1=> Non-Secure state +// Interrupt 347 <0=> Secure state <1=> Non-Secure state +// Interrupt 348 <0=> Secure state <1=> Non-Secure state +// Interrupt 349 <0=> Secure state <1=> Non-Secure state +// Interrupt 350 <0=> Secure state <1=> Non-Secure state +// Interrupt 351 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS10_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 11 (Interrupts 352..383) +*/ +#define NVIC_INIT_ITNS11 0 + +/* +// Interrupts 352..383 +// Interrupt 352 <0=> Secure state <1=> Non-Secure state +// Interrupt 353 <0=> Secure state <1=> Non-Secure state +// Interrupt 354 <0=> Secure state <1=> Non-Secure state +// Interrupt 355 <0=> Secure state <1=> Non-Secure state +// Interrupt 356 <0=> Secure state <1=> Non-Secure state +// Interrupt 357 <0=> Secure state <1=> Non-Secure state +// Interrupt 358 <0=> Secure state <1=> Non-Secure state +// Interrupt 359 <0=> Secure state <1=> Non-Secure state +// Interrupt 360 <0=> Secure state <1=> Non-Secure state +// Interrupt 361 <0=> Secure state <1=> Non-Secure state +// Interrupt 362 <0=> Secure state <1=> Non-Secure state +// Interrupt 363 <0=> Secure state <1=> Non-Secure state +// Interrupt 364 <0=> Secure state <1=> Non-Secure state +// Interrupt 365 <0=> Secure state <1=> Non-Secure state +// Interrupt 366 <0=> Secure state <1=> Non-Secure state +// Interrupt 367 <0=> Secure state <1=> Non-Secure state +// Interrupt 368 <0=> Secure state <1=> Non-Secure state +// Interrupt 369 <0=> Secure state <1=> Non-Secure state +// Interrupt 370 <0=> Secure state <1=> Non-Secure state +// Interrupt 371 <0=> Secure state <1=> Non-Secure state +// Interrupt 372 <0=> Secure state <1=> Non-Secure state +// Interrupt 373 <0=> Secure state <1=> Non-Secure state +// Interrupt 374 <0=> Secure state <1=> Non-Secure state +// Interrupt 375 <0=> Secure state <1=> Non-Secure state +// Interrupt 376 <0=> Secure state <1=> Non-Secure state +// Interrupt 377 <0=> Secure state <1=> Non-Secure state +// Interrupt 378 <0=> Secure state <1=> Non-Secure state +// Interrupt 379 <0=> Secure state <1=> Non-Secure state +// Interrupt 380 <0=> Secure state <1=> Non-Secure state +// Interrupt 381 <0=> Secure state <1=> Non-Secure state +// Interrupt 382 <0=> Secure state <1=> Non-Secure state +// Interrupt 383 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS11_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 12 (Interrupts 384..415) +*/ +#define NVIC_INIT_ITNS12 0 + +/* +// Interrupts 384..415 +// Interrupt 384 <0=> Secure state <1=> Non-Secure state +// Interrupt 385 <0=> Secure state <1=> Non-Secure state +// Interrupt 386 <0=> Secure state <1=> Non-Secure state +// Interrupt 387 <0=> Secure state <1=> Non-Secure state +// Interrupt 388 <0=> Secure state <1=> Non-Secure state +// Interrupt 389 <0=> Secure state <1=> Non-Secure state +// Interrupt 390 <0=> Secure state <1=> Non-Secure state +// Interrupt 391 <0=> Secure state <1=> Non-Secure state +// Interrupt 392 <0=> Secure state <1=> Non-Secure state +// Interrupt 393 <0=> Secure state <1=> Non-Secure state +// Interrupt 394 <0=> Secure state <1=> Non-Secure state +// Interrupt 395 <0=> Secure state <1=> Non-Secure state +// Interrupt 396 <0=> Secure state <1=> Non-Secure state +// Interrupt 397 <0=> Secure state <1=> Non-Secure state +// Interrupt 398 <0=> Secure state <1=> Non-Secure state +// Interrupt 399 <0=> Secure state <1=> Non-Secure state +// Interrupt 400 <0=> Secure state <1=> Non-Secure state +// Interrupt 401 <0=> Secure state <1=> Non-Secure state +// Interrupt 402 <0=> Secure state <1=> Non-Secure state +// Interrupt 403 <0=> Secure state <1=> Non-Secure state +// Interrupt 404 <0=> Secure state <1=> Non-Secure state +// Interrupt 405 <0=> Secure state <1=> Non-Secure state +// Interrupt 406 <0=> Secure state <1=> Non-Secure state +// Interrupt 407 <0=> Secure state <1=> Non-Secure state +// Interrupt 408 <0=> Secure state <1=> Non-Secure state +// Interrupt 409 <0=> Secure state <1=> Non-Secure state +// Interrupt 410 <0=> Secure state <1=> Non-Secure state +// Interrupt 411 <0=> Secure state <1=> Non-Secure state +// Interrupt 412 <0=> Secure state <1=> Non-Secure state +// Interrupt 413 <0=> Secure state <1=> Non-Secure state +// Interrupt 414 <0=> Secure state <1=> Non-Secure state +// Interrupt 415 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS12_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 13 (Interrupts 416..447) +*/ +#define NVIC_INIT_ITNS13 0 + +/* +// Interrupts 416..447 +// Interrupt 416 <0=> Secure state <1=> Non-Secure state +// Interrupt 417 <0=> Secure state <1=> Non-Secure state +// Interrupt 418 <0=> Secure state <1=> Non-Secure state +// Interrupt 419 <0=> Secure state <1=> Non-Secure state +// Interrupt 420 <0=> Secure state <1=> Non-Secure state +// Interrupt 421 <0=> Secure state <1=> Non-Secure state +// Interrupt 422 <0=> Secure state <1=> Non-Secure state +// Interrupt 423 <0=> Secure state <1=> Non-Secure state +// Interrupt 424 <0=> Secure state <1=> Non-Secure state +// Interrupt 425 <0=> Secure state <1=> Non-Secure state +// Interrupt 426 <0=> Secure state <1=> Non-Secure state +// Interrupt 427 <0=> Secure state <1=> Non-Secure state +// Interrupt 428 <0=> Secure state <1=> Non-Secure state +// Interrupt 429 <0=> Secure state <1=> Non-Secure state +// Interrupt 430 <0=> Secure state <1=> Non-Secure state +// Interrupt 431 <0=> Secure state <1=> Non-Secure state +// Interrupt 432 <0=> Secure state <1=> Non-Secure state +// Interrupt 433 <0=> Secure state <1=> Non-Secure state +// Interrupt 434 <0=> Secure state <1=> Non-Secure state +// Interrupt 435 <0=> Secure state <1=> Non-Secure state +// Interrupt 436 <0=> Secure state <1=> Non-Secure state +// Interrupt 437 <0=> Secure state <1=> Non-Secure state +// Interrupt 438 <0=> Secure state <1=> Non-Secure state +// Interrupt 439 <0=> Secure state <1=> Non-Secure state +// Interrupt 440 <0=> Secure state <1=> Non-Secure state +// Interrupt 441 <0=> Secure state <1=> Non-Secure state +// Interrupt 442 <0=> Secure state <1=> Non-Secure state +// Interrupt 443 <0=> Secure state <1=> Non-Secure state +// Interrupt 444 <0=> Secure state <1=> Non-Secure state +// Interrupt 445 <0=> Secure state <1=> Non-Secure state +// Interrupt 446 <0=> Secure state <1=> Non-Secure state +// Interrupt 447 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS13_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 14 (Interrupts 448..479) +*/ +#define NVIC_INIT_ITNS14 0 + +/* +// Interrupts 448..479 +// Interrupt 448 <0=> Secure state <1=> Non-Secure state +// Interrupt 449 <0=> Secure state <1=> Non-Secure state +// Interrupt 450 <0=> Secure state <1=> Non-Secure state +// Interrupt 451 <0=> Secure state <1=> Non-Secure state +// Interrupt 452 <0=> Secure state <1=> Non-Secure state +// Interrupt 453 <0=> Secure state <1=> Non-Secure state +// Interrupt 454 <0=> Secure state <1=> Non-Secure state +// Interrupt 455 <0=> Secure state <1=> Non-Secure state +// Interrupt 456 <0=> Secure state <1=> Non-Secure state +// Interrupt 457 <0=> Secure state <1=> Non-Secure state +// Interrupt 458 <0=> Secure state <1=> Non-Secure state +// Interrupt 459 <0=> Secure state <1=> Non-Secure state +// Interrupt 460 <0=> Secure state <1=> Non-Secure state +// Interrupt 461 <0=> Secure state <1=> Non-Secure state +// Interrupt 462 <0=> Secure state <1=> Non-Secure state +// Interrupt 463 <0=> Secure state <1=> Non-Secure state +// Interrupt 464 <0=> Secure state <1=> Non-Secure state +// Interrupt 465 <0=> Secure state <1=> Non-Secure state +// Interrupt 466 <0=> Secure state <1=> Non-Secure state +// Interrupt 467 <0=> Secure state <1=> Non-Secure state +// Interrupt 468 <0=> Secure state <1=> Non-Secure state +// Interrupt 469 <0=> Secure state <1=> Non-Secure state +// Interrupt 470 <0=> Secure state <1=> Non-Secure state +// Interrupt 471 <0=> Secure state <1=> Non-Secure state +// Interrupt 472 <0=> Secure state <1=> Non-Secure state +// Interrupt 473 <0=> Secure state <1=> Non-Secure state +// Interrupt 474 <0=> Secure state <1=> Non-Secure state +// Interrupt 475 <0=> Secure state <1=> Non-Secure state +// Interrupt 476 <0=> Secure state <1=> Non-Secure state +// Interrupt 477 <0=> Secure state <1=> Non-Secure state +// Interrupt 478 <0=> Secure state <1=> Non-Secure state +// Interrupt 479 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS14_VAL 0x00000000 + +/* +// +*/ + +/* +// Initialize ITNS 15 (Interrupts 480..511) +*/ +#define NVIC_INIT_ITNS15 0 + +/* +// Interrupts 480..511 +// Interrupt 480 <0=> Secure state <1=> Non-Secure state +// Interrupt 481 <0=> Secure state <1=> Non-Secure state +// Interrupt 482 <0=> Secure state <1=> Non-Secure state +// Interrupt 483 <0=> Secure state <1=> Non-Secure state +// Interrupt 484 <0=> Secure state <1=> Non-Secure state +// Interrupt 485 <0=> Secure state <1=> Non-Secure state +// Interrupt 486 <0=> Secure state <1=> Non-Secure state +// Interrupt 487 <0=> Secure state <1=> Non-Secure state +// Interrupt 488 <0=> Secure state <1=> Non-Secure state +// Interrupt 489 <0=> Secure state <1=> Non-Secure state +// Interrupt 490 <0=> Secure state <1=> Non-Secure state +// Interrupt 491 <0=> Secure state <1=> Non-Secure state +// Interrupt 492 <0=> Secure state <1=> Non-Secure state +// Interrupt 493 <0=> Secure state <1=> Non-Secure state +// Interrupt 494 <0=> Secure state <1=> Non-Secure state +// Interrupt 495 <0=> Secure state <1=> Non-Secure state +// Interrupt 496 <0=> Secure state <1=> Non-Secure state +// Interrupt 497 <0=> Secure state <1=> Non-Secure state +// Interrupt 498 <0=> Secure state <1=> Non-Secure state +// Interrupt 499 <0=> Secure state <1=> Non-Secure state +// Interrupt 500 <0=> Secure state <1=> Non-Secure state +// Interrupt 501 <0=> Secure state <1=> Non-Secure state +// Interrupt 502 <0=> Secure state <1=> Non-Secure state +// Interrupt 503 <0=> Secure state <1=> Non-Secure state +// Interrupt 504 <0=> Secure state <1=> Non-Secure state +// Interrupt 505 <0=> Secure state <1=> Non-Secure state +// Interrupt 506 <0=> Secure state <1=> Non-Secure state +// Interrupt 507 <0=> Secure state <1=> Non-Secure state +// Interrupt 508 <0=> Secure state <1=> Non-Secure state +// Interrupt 509 <0=> Secure state <1=> Non-Secure state +// Interrupt 510 <0=> Secure state <1=> Non-Secure state +// Interrupt 511 <0=> Secure state <1=> Non-Secure state +*/ +#define NVIC_INIT_ITNS15_VAL 0x00000000 + +/* +// +*/ + +/* +// +*/ + + + +/* + max 128 SAU regions. + SAU regions are defined in partition.h + */ + +#define SAU_INIT_REGION(n) \ + SAU->RNR = (n & SAU_RNR_REGION_Msk); \ + SAU->RBAR = (SAU_INIT_START##n & SAU_RBAR_BADDR_Msk); \ + SAU->RLAR = (SAU_INIT_END##n & SAU_RLAR_LADDR_Msk) | \ + ((SAU_INIT_NSC##n << SAU_RLAR_NSC_Pos) & SAU_RLAR_NSC_Msk) | 1U + +/** + \brief Setup a SAU Region + \details Writes the region information contained in SAU_Region to the + registers SAU_RNR, SAU_RBAR, and SAU_RLAR + */ +__STATIC_INLINE void TZ_SAU_Setup (void) +{ + +#if defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) + + #if defined (SAU_INIT_REGION0) && (SAU_INIT_REGION0 == 1U) + SAU_INIT_REGION(0); + #endif + + #if defined (SAU_INIT_REGION1) && (SAU_INIT_REGION1 == 1U) + SAU_INIT_REGION(1); + #endif + + #if defined (SAU_INIT_REGION2) && (SAU_INIT_REGION2 == 1U) + SAU_INIT_REGION(2); + #endif + + #if defined (SAU_INIT_REGION3) && (SAU_INIT_REGION3 == 1U) + SAU_INIT_REGION(3); + #endif + + #if defined (SAU_INIT_REGION4) && (SAU_INIT_REGION4 == 1U) + SAU_INIT_REGION(4); + #endif + + #if defined (SAU_INIT_REGION5) && (SAU_INIT_REGION5 == 1U) + SAU_INIT_REGION(5); + #endif + + #if defined (SAU_INIT_REGION6) && (SAU_INIT_REGION6 == 1U) + SAU_INIT_REGION(6); + #endif + + #if defined (SAU_INIT_REGION7) && (SAU_INIT_REGION7 == 1U) + SAU_INIT_REGION(7); + #endif + + /* repeat this for all possible SAU regions */ + +#endif /* defined (__SAUREGION_PRESENT) && (__SAUREGION_PRESENT == 1U) */ + + + #if defined (SAU_INIT_CTRL) && (SAU_INIT_CTRL == 1U) + SAU->CTRL = ((SAU_INIT_CTRL_ENABLE << SAU_CTRL_ENABLE_Pos) & SAU_CTRL_ENABLE_Msk) | + ((SAU_INIT_CTRL_ALLNS << SAU_CTRL_ALLNS_Pos) & SAU_CTRL_ALLNS_Msk) ; + #endif + + #if defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) + SCB->SCR = (SCB->SCR & ~(SCB_SCR_SLEEPDEEPS_Msk )) | + ((SCB_CSR_DEEPSLEEPS_VAL << SCB_SCR_SLEEPDEEPS_Pos) & SCB_SCR_SLEEPDEEPS_Msk); + + SCB->AIRCR = (SCB->AIRCR & ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_SYSRESETREQS_Msk | + SCB_AIRCR_BFHFNMINS_Msk | SCB_AIRCR_PRIS_Msk )) | + ((0x05FAU << SCB_AIRCR_VECTKEY_Pos) & SCB_AIRCR_VECTKEY_Msk) | + ((SCB_AIRCR_SYSRESETREQS_VAL << SCB_AIRCR_SYSRESETREQS_Pos) & SCB_AIRCR_SYSRESETREQS_Msk) | + ((SCB_AIRCR_PRIS_VAL << SCB_AIRCR_PRIS_Pos) & SCB_AIRCR_PRIS_Msk) | + ((SCB_AIRCR_BFHFNMINS_VAL << SCB_AIRCR_BFHFNMINS_Pos) & SCB_AIRCR_BFHFNMINS_Msk); + #endif /* defined (SCB_CSR_AIRCR_INIT) && (SCB_CSR_AIRCR_INIT == 1U) */ + + #if (((defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0))) && \ + (defined (TZ_FPU_NS_USAGE) && (TZ_FPU_NS_USAGE == 1U))) + + SCB->NSACR = (SCB->NSACR & ~(SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)) | + ((SCB_NSACR_CP10_11_VAL << SCB_NSACR_CP10_Pos) & (SCB_NSACR_CP10_Msk | SCB_NSACR_CP11_Msk)); + + FPU->FPCCR = (FPU->FPCCR & ~(FPU_FPCCR_TS_Msk | FPU_FPCCR_CLRONRETS_Msk | FPU_FPCCR_CLRONRET_Msk)) | + ((FPU_FPCCR_TS_VAL << FPU_FPCCR_TS_Pos ) & FPU_FPCCR_TS_Msk ) | + ((FPU_FPCCR_CLRONRETS_VAL << FPU_FPCCR_CLRONRETS_Pos) & FPU_FPCCR_CLRONRETS_Msk) | + ((FPU_FPCCR_CLRONRET_VAL << FPU_FPCCR_CLRONRET_Pos ) & FPU_FPCCR_CLRONRET_Msk ); + #endif + + #if defined (NVIC_INIT_ITNS0) && (NVIC_INIT_ITNS0 == 1U) + NVIC->ITNS[0] = NVIC_INIT_ITNS0_VAL; + #endif + + #if defined (NVIC_INIT_ITNS1) && (NVIC_INIT_ITNS1 == 1U) + NVIC->ITNS[1] = NVIC_INIT_ITNS1_VAL; + #endif + + #if defined (NVIC_INIT_ITNS2) && (NVIC_INIT_ITNS2 == 1U) + NVIC->ITNS[2] = NVIC_INIT_ITNS2_VAL; + #endif + + #if defined (NVIC_INIT_ITNS3) && (NVIC_INIT_ITNS3 == 1U) + NVIC->ITNS[3] = NVIC_INIT_ITNS3_VAL; + #endif + + #if defined (NVIC_INIT_ITNS4) && (NVIC_INIT_ITNS4 == 1U) + NVIC->ITNS[4] = NVIC_INIT_ITNS4_VAL; + #endif + + #if defined (NVIC_INIT_ITNS5) && (NVIC_INIT_ITNS5 == 1U) + NVIC->ITNS[5] = NVIC_INIT_ITNS5_VAL; + #endif + + #if defined (NVIC_INIT_ITNS6) && (NVIC_INIT_ITNS6 == 1U) + NVIC->ITNS[6] = NVIC_INIT_ITNS6_VAL; + #endif + + #if defined (NVIC_INIT_ITNS7) && (NVIC_INIT_ITNS7 == 1U) + NVIC->ITNS[7] = NVIC_INIT_ITNS7_VAL; + #endif + + #if defined (NVIC_INIT_ITNS8) && (NVIC_INIT_ITNS8 == 1U) + NVIC->ITNS[8] = NVIC_INIT_ITNS8_VAL; + #endif + + #if defined (NVIC_INIT_ITNS9) && (NVIC_INIT_ITNS9 == 1U) + NVIC->ITNS[9] = NVIC_INIT_ITNS9_VAL; + #endif + + #if defined (NVIC_INIT_ITNS10) && (NVIC_INIT_ITNS10 == 1U) + NVIC->ITNS[10] = NVIC_INIT_ITNS10_VAL; + #endif + + #if defined (NVIC_INIT_ITNS11) && (NVIC_INIT_ITNS11 == 1U) + NVIC->ITNS[11] = NVIC_INIT_ITNS11_VAL; + #endif + + #if defined (NVIC_INIT_ITNS12) && (NVIC_INIT_ITNS12 == 1U) + NVIC->ITNS[12] = NVIC_INIT_ITNS12_VAL; + #endif + + #if defined (NVIC_INIT_ITNS13) && (NVIC_INIT_ITNS13 == 1U) + NVIC->ITNS[13] = NVIC_INIT_ITNS13_VAL; + #endif + + #if defined (NVIC_INIT_ITNS14) && (NVIC_INIT_ITNS14 == 1U) + NVIC->ITNS[14] = NVIC_INIT_ITNS14_VAL; + #endif + + #if defined (NVIC_INIT_ITNS15) && (NVIC_INIT_ITNS15 == 1U) + NVIC->ITNS[15] = NVIC_INIT_ITNS15_VAL; + #endif + + /* repeat this for all possible ITNS elements */ + +} + +#endif /* PARTITION_CS300_H */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h new file mode 100644 index 000000000..b813097f5 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2019-2021 Arm Limited + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file platform_base_address.h + * \brief This file defines all the peripheral base addresses for AN552 MPS3 SSE-300 + + * Ethos-U55 platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H__ +#define __PLATFORM_BASE_ADDRESS_H__ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ITCM_BASE_NS 0x00000000 /* Instruction TCM Non-Secure base address */ +#define SRAM_BASE_NS 0x01000000 /* CODE SRAM Non-Secure base address */ +#define DTCM0_BASE_NS 0x20000000 /* Data TCM block 0 Non-Secure base address */ +#define DTCM1_BASE_NS 0x20020000 /* Data TCM block 1 Non-Secure base address */ +#define DTCM2_BASE_NS 0x20040000 /* Data TCM block 2 Non-Secure base address */ +#define DTCM3_BASE_NS 0x20060000 /* Data TCM block 3 Non-Secure base address */ +#define ISRAM0_BASE_NS 0x21000000 /* Internal SRAM Area Non-Secure base address */ +#define ISRAM1_BASE_NS 0x21100000 /* Internal SRAM Area Non-Secure base address */ +#define QSPI_SRAM_BASE_NS 0x28000000 /* QSPI SRAM Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */ +#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */ +#define SSE300_NSACFG_BASE_NS 0x40080000 /* SSE-300 Non-Secure Access Configuration Register Block Non-Secure base address */ +/* Non-Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_NS 0x41100000 /* GPIO 0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x41101000 /* GPIO 1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x41102000 /* GPIO 2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x41103000 /* GPIO 3 Non-Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_NS 0x41104000 /* FMC CMSDK GPIO 0 Non-Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_NS 0x41105000 /* FMC CMSDK GPIO 1 Non-Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_NS 0x41106000 /* FMC CMSDK GPIO 2 Non-Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_NS 0x41107000 /* FMC CMSDK GPIO 3 Non-Secure base address */ +#define EXTERNAL_MANAGER_0_BASE_NS 0x41200000 /* External manager 0 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_1_BASE_NS 0x41201000 /* External manager 1 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_2_BASE_NS 0x41202000 /* External manager 2 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_3_BASE_NS 0x41203000 /* External manager 3 (Unused) Non-Secure base address */ +#define ETHERNET_BASE_NS 0x41400000 /* Ethernet Non-Secure base address */ +#define USB_BASE_NS 0x41500000 /* USB Non-Secure base address */ +#define USER_APB0_BASE_NS 0x41700000 /* User APB 0 Non-Secure base address */ +#define USER_APB1_BASE_NS 0x41701000 /* User APB 1 Non-Secure base address */ +#define USER_APB2_BASE_NS 0x41702000 /* User APB 2 Non-Secure base address */ +#define USER_APB3_BASE_NS 0x41703000 /* User APB 3 Non-Secure base address */ +#define QSPI_CONFIG_BASE_NS 0x41800000 /* QSPI Config Non-Secure base address */ +#define QSPI_WRITE_BASE_NS 0x41801000 /* QSPI Write Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_NS 0x48000000 /* System Timer 0 Non-Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_NS 0x48001000 /* System Timer 1 Non-Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_NS 0x48002000 /* System Timer 2 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 3 Non-Secure base address */ +#define SSE300_SYSINFO_BASE_NS 0x48020000 /* SSE-300 System info Block Non-Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_NS 0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS 0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_NS 0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48101000 /* System Counter Read Secure base address */ +/* Non-Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_NS 0x48102000 /* Ethos-U55 APB Non-Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_NS 0x48103000 /* Ethos-U55 Timing Adapter 0 APB registers Non-Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_NS 0x48103200 /* Ethos-U55 Timing Adapter 1 APB registers Non-Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_NS 0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */ +#define FPGA_SPI_ADC_BASE_NS 0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_NS 0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_NS 0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_NS 0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_NS 0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */ +#define USER_APB_BASE_NS 0x49207000 /* USER APB Non-Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_NS 0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */ +#define FMC_USER_APB0 0x4920C000 /* FMC User APB0 */ +#define FMC_USER_APB1 0x4920D000 /* FMC User APB1 */ +#define FMC_USER_APB2 0x4920E000 /* FMC User APB2 */ +#define FMC_USER_APB3 0x4920F000 /* FMC User APB3 */ +#define FPGA_SCC_BASE_NS 0x49300000 /* FPGA - SCC registers Non-Secure base address */ +#define FPGA_I2S_BASE_NS 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */ +#define FPGA_IO_BASE_NS 0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */ +#define UART0_BASE_NS 0x49303000 /* UART 0 Non-Secure base address */ +#define UART1_BASE_NS 0x49304000 /* UART 1 Non-Secure base address */ +#define UART2_BASE_NS 0x49305000 /* UART 2 Non-Secure base address */ +#define UART3_BASE_NS 0x49306000 /* UART 3 Non-Secure base address */ +#define UART4_BASE_NS 0x49307000 /* UART 4 Non-Secure base address */ +#define UART5_BASE_NS 0x49308000 /* UART 5 Non-Secure base address */ +#define CLCD_Config_Reg_BASE_NS 0x4930A000 /* CLCD Config Reg Non-Secure base address */ +#define RTC_BASE_NS 0x4930B000 /* RTC Non-Secure base address */ +#define DDR4_BLK0_BASE_NS 0x60000000 /* DDR4 block 0 Non-Secure base address */ +#define DDR4_BLK2_BASE_NS 0x80000000 /* DDR4 block 2 Non-Secure base address */ +#define DDR4_BLK4_BASE_NS 0xA0000000 /* DDR4 block 4 Non-Secure base address */ +#define DDR4_BLK6_BASE_NS 0xC0000000 /* DDR4 block 6 Non-Secure base address */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define SRAM_BASE_S 0x11000000 /* CODE SRAM Secure base address */ +#define DTCM0_BASE_S 0x30000000 /* Data TCM block 0 Secure base address */ +#define DTCM1_BASE_S 0x30020000 /* Data TCM block 1 Secure base address */ +#define DTCM2_BASE_S 0x30040000 /* Data TCM block 2 Secure base address */ +#define DTCM3_BASE_S 0x30060000 /* Data TCM block 3 Secure base address */ +#define ISRAM0_BASE_S 0x31000000 /* Internal SRAM Area Secure base address */ +#define ISRAM1_BASE_S 0x31100000 /* Internal SRAM Area Secure base address */ +#define QSPI_SRAM_BASE_S 0x38000000 /* QSPI SRAM Secure base address */ +/* Secure Subsystem peripheral region */ +#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */ +#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */ +#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */ +#define SSE300_SACFG_BASE_S 0x50080000 /* SSE-300 Secure Access Configuration Register Secure base address */ +#define MPC_ISRAM0_BASE_S 0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */ +#define MPC_ISRAM1_BASE_S 0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */ +/* Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_S 0x51100000 /* GPIO 0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x51101000 /* GPIO 1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x51102000 /* GPIO 2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x51103000 /* GPIO 3 Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_S 0x51104000 /* FMC CMSDK GPIO 0 Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_S 0x51105000 /* FMC CMSDK GPIO 1 Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_S 0x51106000 /* FMC CMSDK GPIO 2 Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_S 0x51107000 /* FMC CMSDK GPIO 3 Secure base address */ +#define EXTERNAL_MANAGER0_BASE_S 0x51200000 /* External Manager 0 (Unused) Secure base address */ +#define EXTERNAL_MANAGER1_BASE_S 0x51201000 /* External Manager 1 (Unused) Secure base address */ +#define EXTERNAL_MANAGER2_BASE_S 0x51202000 /* External Manager 2 (Unused) Secure base address */ +#define EXTERNAL_MANAGER3_BASE_S 0x51203000 /* External Manager 3 (Unused) Secure base address */ +#define ETHERNET_BASE_S 0x51400000 /* Ethernet Secure base address */ +#define USB_BASE_S 0x51500000 /* USB Secure base address */ +#define USER_APB0_BASE_S 0x51700000 /* User APB 0 Secure base address */ +#define USER_APB1_BASE_S 0x51701000 /* User APB 1 Secure base address */ +#define USER_APB2_BASE_S 0x51702000 /* User APB 2 Secure base address */ +#define USER_APB3_BASE_S 0x51703000 /* User APB 3 Secure base address */ +#define QSPI_CONFIG_BASE_S 0x51800000 /* QSPI Config Secure base address */ +#define QSPI_WRITE_BASE_S 0x51801000 /* QSPI Write Secure base address */ +#define MPC_SRAM_BASE_S 0x57000000 /* SRAM Memory Protection Controller Secure base address */ +#define MPC_QSPI_BASE_S 0x57001000 /* QSPI Memory Protection Controller Secure base address */ +#define MPC_DDR4_BASE_S 0x57002000 /* DDR4 Memory Protection Controller Secure base address */ +/* Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_S 0x58000000 /* System Timer 0 Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_S 0x58001000 /* System Timer 1 Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_S 0x58002000 /* System Timer 0 Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_S 0x58003000 /* System Timer 1 Secure base address */ +#define SSE300_SYSINFO_BASE_S 0x58020000 /* SSE-300 System info Block Secure base address */ +#define SSE300_SYSCTRL_BASE_S 0x58021000 /* SSE-300 System control Block Secure base address */ +#define SSE300_SYSPPU_BASE_S 0x58022000 /* SSE-300 System Power Policy Unit Secure base address */ +#define SSE300_CPU0PPU_BASE_S 0x58023000 /* SSE-300 CPU 0 Power Policy Unit Secure base address */ +#define SSE300_MGMTPPU_BASE_S 0x58028000 /* SSE-300 Management Power Policy Unit Secure base address */ +#define SSE300_DBGPPU_BASE_S 0x58029000 /* SSE-300 Debug Power Policy Unit Secure base address */ +#define SLOWCLK_WDOG_CMSDK_BASE_S 0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_S 0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_S 0x58040000 /* Secure Watchdog Timer control frame Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_S 0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58100000 /* System Counter Control Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58101000 /* System Counter Read Secure base address */ +/* Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_S 0x58102000 /* Ethos-U55 APB Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_S 0x58103000 /* Ethos-U55 Timing Adapter 0 APB registers Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_S 0x58103200 /* Ethos-U55 Timing Adapter 1 APB registers Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_S 0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */ +#define FPGA_SPI_ADC_BASE_S 0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_S 0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_S 0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_S 0x59205000 /* SBCon (I2C - Shield0) Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_S 0x59206000 /* SBCon (I2C – Shield1) Secure base address */ +#define USER_APB_BASE_S 0x59207000 /* USER APB Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_S 0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */ +#define FMC_USER_APB_0_BASE_S 0x5920C000 /* FMC User APB0 registers Secure base address */ +#define FMC_USER_APB_1_BASE_S 0x5920D000 /* FMC User APB1 registers Secure base address */ +#define FMC_USER_APB_2_BASE_S 0x5920E000 /* FMC User APB2 registers Secure base address */ +#define FMC_USER_APB_3_BASE_S 0x5920F000 /* FMC User APB3 registers Secure base address */ +#define FPGA_SCC_BASE_S 0x59300000 /* FPGA - SCC registers Secure base address */ +#define FPGA_I2S_BASE_S 0x59301000 /* FPGA - I2S (Audio) Secure base address */ +#define FPGA_IO_BASE_S 0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */ +#define UART0_BASE_S 0x59303000 /* UART 0 Secure base address */ +#define UART1_BASE_S 0x59304000 /* UART 1 Secure base address */ +#define UART2_BASE_S 0x59305000 /* UART 2 Secure base address */ +#define UART3_BASE_S 0x59306000 /* UART 3 Secure base address */ +#define UART4_BASE_S 0x59307000 /* UART 4 Secure base address */ +#define UART5_BASE_S 0x59308000 /* UART 5 Secure base address */ +#define CLCD_Config_Reg_BASE_S 0x5930A000 /* CLCD Config Reg Secure base address */ +#define RTC_BASE_S 0x5930B000 /* RTC Secure base address */ +#define DDR4_BLK1_BASE_S 0x70000000 /* DDR4 block 1 Secure base address */ +#define DDR4_BLK3_BASE_S 0x90000000 /* DDR4 block 3 Secure base address */ +#define DDR4_BLK5_BASE_S 0xB0000000 /* DDR4 block 5 Secure base address */ +#define DDR4_BLK7_BASE_S 0xD0000000 /* DDR4 block 7 Secure base address */ + +/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */ +#define SSE300_EWIC_BASE 0xE0047000 /* External Wakeup Interrupt Controller + * Access from Non-secure software is only allowed + * if AIRCR.BFHFNMINS is set to 1 */ + +/* Memory size definitions */ +#define ITCM_SIZE (0x00080000) /* 512 kB */ +#define DTCM_BLK_SIZE (0x00020000) /* 128 kB */ +#define DTCM_BLK_NUM (0x4) /* Number of DTCM blocks */ +#define SRAM_SIZE (0x00100000) /* 1 MB */ +#define ISRAM0_SIZE (0x00100000) /* 1 MB */ +#define ISRAM1_SIZE (0x00100000) /* 1 MB */ +#define QSPI_SRAM_SIZE (0x00800000) /* 8 MB */ +#define DDR4_BLK_SIZE (0x10000000) /* 256 MB */ +#define DDR4_BLK_NUM (0x8) /* Number of DDR4 blocks */ + +/* Defines for Driver MPC's */ +/* SRAM -- 2 MB */ +#define MPC_SRAM_RANGE_BASE_NS (SRAM_BASE_NS) +#define MPC_SRAM_RANGE_LIMIT_NS (SRAM_BASE_NS + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_NS (0x0) +#define MPC_SRAM_RANGE_BASE_S (SRAM_BASE_S) +#define MPC_SRAM_RANGE_LIMIT_S (SRAM_BASE_S + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_S (0x0) + +/* QSPI -- 8 MB*/ +#define MPC_QSPI_RANGE_BASE_NS (QSPI_SRAM_BASE_NS) +#define MPC_QSPI_RANGE_LIMIT_NS (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_NS (0x0) +#define MPC_QSPI_RANGE_BASE_S (QSPI_SRAM_BASE_S) +#define MPC_QSPI_RANGE_LIMIT_S (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_S (0x0) + +/* ISRAM0 -- 2 MB*/ +#define MPC_ISRAM0_RANGE_BASE_NS (ISRAM0_BASE_NS) +#define MPC_ISRAM0_RANGE_LIMIT_NS (ISRAM0_BASE_NS + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM0_RANGE_BASE_S (ISRAM0_BASE_S) +#define MPC_ISRAM0_RANGE_LIMIT_S (ISRAM0_BASE_S + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_S (0x0) + +/* ISRAM1 -- 2 MB*/ +#define MPC_ISRAM1_RANGE_BASE_NS (ISRAM1_BASE_NS) +#define MPC_ISRAM1_RANGE_LIMIT_NS (ISRAM1_BASE_NS + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM1_RANGE_BASE_S (ISRAM1_BASE_S) +#define MPC_ISRAM1_RANGE_LIMIT_S (ISRAM1_BASE_S + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_S (0x0) + +/* DDR4 -- 2GB (8 * 256 MB) */ +#define MPC_DDR4_BLK0_RANGE_BASE_NS (DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK0_RANGE_LIMIT_NS (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK0_RANGE_OFFSET_NS (0x0) +#define MPC_DDR4_BLK1_RANGE_BASE_S (DDR4_BLK1_BASE_S) +#define MPC_DDR4_BLK1_RANGE_LIMIT_S (DDR4_BLK1_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK1_RANGE_OFFSET_S (DDR4_BLK1_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_BASE_NS (DDR4_BLK2_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_LIMIT_NS (DDR4_BLK2_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK2_RANGE_OFFSET_NS (DDR4_BLK2_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK3_RANGE_BASE_S (DDR4_BLK3_BASE_S) +#define MPC_DDR4_BLK3_RANGE_LIMIT_S (DDR4_BLK3_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK3_RANGE_OFFSET_S (DDR4_BLK3_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_BASE_NS (DDR4_BLK4_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_LIMIT_NS (DDR4_BLK4_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK4_RANGE_OFFSET_NS (DDR4_BLK4_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK5_RANGE_BASE_S (DDR4_BLK5_BASE_S) +#define MPC_DDR4_BLK5_RANGE_LIMIT_S (DDR4_BLK5_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK5_RANGE_OFFSET_S (DDR4_BLK5_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_BASE_NS (DDR4_BLK6_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_LIMIT_NS (DDR4_BLK6_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK6_RANGE_OFFSET_NS (DDR4_BLK6_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK7_RANGE_BASE_S (DDR4_BLK7_BASE_S) +#define MPC_DDR4_BLK7_RANGE_LIMIT_S (DDR4_BLK7_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK7_RANGE_OFFSET_S (DDR4_BLK7_BASE_S - DDR4_BLK0_BASE_NS) + +#endif /* __PLATFORM_BASE_ADDRESS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h new file mode 100644 index 000000000..32ac16b37 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016-2022 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "region_limits.h" + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure regions */ +#define S_CODE_START ( S_ROM_ALIAS ) +#define S_CODE_SIZE ( TOTAL_S_ROM_SIZE ) +#define S_CODE_LIMIT ( S_CODE_START + S_CODE_SIZE ) + +#define S_DATA_START ( S_RAM_ALIAS ) +#define S_DATA_SIZE ( TOTAL_S_RAM_SIZE ) +#define S_DATA_LIMIT ( S_DATA_START + S_DATA_SIZE ) + +#define S_DDR4_START ( S_DDR4_ALIAS ) +#define S_DDR4_SIZE ( TOTAL_S_DDR4_SIZE ) +#define S_DDR4_LIMIT ( S_DDR4_START + S_DDR4_SIZE ) + +#endif /* __REGION_DEFS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h new file mode 100644 index 000000000..e7897866a --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2022 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_LIMITS_H__ +#define __REGION_LIMITS_H__ + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure Code */ +#define S_ROM_ALIAS (0x10000000) /* ITCM_BASE_S */ +#define TOTAL_S_ROM_SIZE (0x00080000) /* 512 kB */ + +/* Secure Data */ +#define S_RAM_ALIAS (0x30000000) /* DTCM_BASE_S */ +#define TOTAL_S_RAM_SIZE (0x00080000) /* 512 kB */ + +/* Secure DDR4 */ +#define S_DDR4_ALIAS (0x70000000) /* DDR4_BLK1_BASE_S */ +#define TOTAL_S_DDR4_SIZE (0x10000000) /* 256 MB */ + +/* Heap and Stack sizes for secure and nonsecure applications */ +#define HEAP_SIZE (0x00000400) /* 1 KiB */ +#define STACK_SIZE (0x00000400) /* 1 KiB */ + +#endif /* __REGION_LIMITS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c new file mode 100644 index 000000000..d1e59d74a --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "SSE300MPS3.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK __NO_RETURN handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TIMER0_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TIMER0_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c new file mode 100644 index 000000000..ce3ad1611 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2009-2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "SSE300MPS3.h" + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + #include "partition_CS300.h" +#endif + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ + #define XTAL (32000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Externals + *----------------------------------------------------------------------------*/ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + extern uint32_t __VECTOR_TABLE; +#endif + + + +/*****************************************************************/ +/*------------------- Memory Protection Controller -----------------------------*/ +typedef struct +{ + __IOM uint32_t CTRL; /* Offset: 0x000 (R/W) Control Register */ + uint32_t RESERVED0[3]; + __IM uint32_t BLK_MAX; /* Offset: 0x010 (R/ ) Block Maximum Register */ + __IM uint32_t BLK_CFG; /* Offset: 0x014 (R/ ) Block Configuration Register */ + __IOM uint32_t BLK_IDX; /* Offset: 0x018 (R/W) Block Index Register */ + __IOM uint32_t BLK_LUT; /* Offset: 0x01C (R/W) Block Lookup Tabe Register */ + __IM uint32_t INT_STAT; /* Offset: 0x020 (R/ ) Interrupt Status Register */ + __OM uint32_t INT_CLEAR; /* Offset: 0x024 ( /W) Interrupt Clear Register */ + __IOM uint32_t INT_EN; /* Offset: 0x028 (R/W) Interrupt Enable Register */ + __IM uint32_t INT_INFO1; /* Offset: 0x02C (R/ ) Interrupt Info1 Register */ + __IM uint32_t INT_INFO2; /* Offset: 0x030 (R/ ) Interrupt Info2 Register */ + __OM uint32_t INT_SET; /* Offset: 0x034 ( /W) Interrupt Set Register */ +} MPC_TypeDef; + +#define MPC_SRAM ((MPC_TypeDef *) MPC_SRAM_BASE_S ) +#define MPC_ISRAM0 ((MPC_TypeDef *) MPC_ISRAM0_BASE_S ) + + +/*------------------- Secure Privilege Control Block -----------------------------*/ +typedef struct +{ + uint32_t RESERVED0[5U]; + __IOM uint32_t NSCCFG; /* Offset: 0x014 (R/W) Non Secure Callable Configuration for IDAU */ +} SAC_TypeDef; + +#define SAC ((SAC_TypeDef *) SSE300_SACFG_BASE_S ) + + +/*------------------- TCM Gating Unit --------------------------------------------*/ +typedef struct /* see "Arm Cortex-Mxx Technical Reference Manual r0p1" +" */ +{ + __IOM uint32_t CTRL; /* Offset: 0x000 (R/W) Gate Control Register */ + __IM uint32_t CFG; /* Offset: 0x004 (R/ ) Gate Configuration Register */ + uint32_t RESERVED0[2]; + __IOM uint32_t LUT[16]; /* Offset: 0x010 (R/W) Gate Look-up Table Register */ +} TGU_TypeDef; + +#define ITGU_BASE (0xE001E500UL) /* ITCM Gating Unit */ +#define DTGU_BASE (0xE001E600UL) /* DTCM Gating Unit */ + +#define ITGU ((TGU_TypeDef *) ITGU_BASE) +#define DTGU ((TGU_TypeDef *) DTGU_BASE) +/*****************************************************************/ + + + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE); +#endif + +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE > 0U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); /* enable CP11 Full Access */ + + /* Set low-power state for PDEPU */ + /* 0b00 | ON, PDEPU is not in low-power state */ + /* 0b01 | ON, but the clock is off */ + /* 0b10 | RET(ention) */ + /* 0b11 | OFF */ + + /* Clear ELPSTATE, value is 0b11 on Cold reset */ + PWRMODCTL->CPDLPSTATE &= ~(PWRMODCTL_CPDLPSTATE_ELPSTATE_Msk); + + /* Favor best FP/MVE performance by default, avoid EPU switch-ON delays */ + /* PDEPU ON, Clock OFF */ + PWRMODCTL->CPDLPSTATE |= 0x1 << PWRMODCTL_CPDLPSTATE_ELPSTATE_Pos; +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + + /* Enable Loop and branch info cache */ + SCB->CCR |= SCB_CCR_LOB_Msk; + __DSB(); + __ISB(); + + +#if defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3U) + /* Enable BusFault, UsageFault, MemManageFault and SecureFault to ease diagnostic */ + SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | + SCB_SHCSR_BUSFAULTENA_Msk | + SCB_SHCSR_MEMFAULTENA_Msk | + SCB_SHCSR_SECUREFAULTENA_Msk); + + /* BFSR register setting to enable precise errors */ + SCB->CFSR |= SCB_CFSR_PRECISERR_Msk; + + /* configure unsecure code area: ITCM 512K 0x00080000 - 0x00100000 */ + // blk_cfg = ITGU->CFG & 0xF; /* = 0x7 */ + // blk_size = 1UL << (blk_cfg + 5U); /* = 0x1000 (4K) */ + ITGU->LUT[4] = 0xFFFFFFFF; + ITGU->LUT[5] = 0xFFFFFFFF; + ITGU->LUT[6] = 0xFFFFFFFF; + ITGU->LUT[7] = 0xFFFFFFFF; + + /* configure unsecure data area: DTCM 512K 0x20080000 - 0x20100000 */ + // blk_cfg = DTGU->CFG & 0xF; /* = 0x7 */ + // blk_size = 1UL << (blk_cfg + 5U); /* = 0x1000 (4K) */ + DTGU->LUT[4] = 0xFFFFFFFF; + DTGU->LUT[5] = 0xFFFFFFFF; + DTGU->LUT[6] = 0xFFFFFFFF; + DTGU->LUT[7] = 0xFFFFFFFF; + + /* Non Secure Callable Configuration for IDAU (NSCCFG register) */ + SAC->NSCCFG |= 1U; /* Configure CODE region (0x1000_0000 to 0x1FFF_FFFF) Non-secure Callable */ +//SAC->NSCCFG |= 2U; /* Configure RAM region (0x3000_0000 to 0x3FFF_FFFF) Non-secure Callable */ + + + TZ_SAU_Setup(); +#endif + + SystemCoreClock = SYSTEM_CLOCK; +} diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h new file mode 100644 index 000000000..feba5e9aa --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.h + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#ifndef __SYSTEM_CORE_INIT_H__ +#define __SYSTEM_CORE_INIT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency */ + +/** + * \brief Initializes the system + */ +extern void SystemInit(void); + +/** + * \brief Restores system core clock + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_CORE_INIT_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h new file mode 100644 index 000000000..c7f94da92 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h @@ -0,0 +1,21 @@ + +/* + * Auto generated Run-Time-Environment Configuration File + * *** Do not modify ! *** + * + * Project: 'demo_secure_zone' + * Target: 'FVP Simulation Model' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "SSE300MPS3.h" + + + +#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvoptx b/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvoptx new file mode 100644 index 000000000..92bdbefe4 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvoptx @@ -0,0 +1,366 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + FVP Simulation Model + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + ..\Debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FC1000 -FD01000000 + + + 0 + DbgFMv8M + -I -S"System Generator:cpu_core" -L"cpu0" -O4102 -C0 -MC"$K\ARM\VHT\VHT_MPS3_Corstone_SSE-300.exe" -MF"..\CS300_config.txt" -PF -MA + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=4619,189,4877,920,0)(6015=3743,140,4001,762,0)(6003=-1,-1,-1,-1,0)(6000=4424,206,4877,538,0)(6020=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + + + 0 + 0 + 48 + 1 +
268439734
+ 0 + 0 + 0 + 0 + 0 + 1 + <1>.\main_s.c + + \\secure_app\main_s.c\48 +
+
+ + + 0 + 1 + thread_0_counter + + + 1 + 1 + thread_1_counter + + + 2 + 1 + thread_2_counter + + + 3 + 1 + thread_3_counter + + + 4 + 1 + thread_4_counter + + + 5 + 1 + thread_5_counter + + + 6 + 1 + thread_6_counter + + + 7 + 1 + thread_7_counter + + + + + 1 + 2 + 0x01000400 + 0 + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + +
+
+ + + Secure Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\main_s.c + main_s.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\src\tx_thread_secure_stack.c + tx_thread_secure_stack.c + 0 + 0 + + + 1 + 3 + 2 + 0 + 0 + 0 + ..\..\src\tx_thread_interrupt_disable.S + tx_thread_interrupt_disable.S + 0 + 0 + + + 1 + 4 + 2 + 0 + 0 + 0 + ..\..\src\tx_thread_interrupt_restore.S + tx_thread_interrupt_restore.S + 0 + 0 + + + + + Interface + 1 + 0 + 0 + 0 + + 2 + 5 + 1 + 0 + 0 + 0 + .\interface.c + interface.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + + ::Device + 0 + 0 + 0 + 1 + + + + ::Native Driver + 0 + 0 + 0 + 1 + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvprojx b/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvprojx new file mode 100644 index 000000000..4f3f8327c --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/demo_secure_zone.uvprojx @@ -0,0 +1,580 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + FVP Simulation Model + 0x4 + ARM-ADS + 6180000::V6.18::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.3.0 + http://www.keil.com/pack/ + IRAM(0x00000000,0x00080000) IRAM2(0x01000000,0x00200000) XRAM(0x20000000,0x00020000) XRAM2(0x20020000,0x00020000) XRAM3(0x20040000,0x00020000) CPUTYPE("Cortex-M55") FPU3(DFPU) DSP TZ MVE(FP) CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Device\Include\SSE300MPS3.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + secure_app + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU -MVE + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + 4102 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 3 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 1 + 0 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x200000 + + + 1 + 0x20000000 + 0x20000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x20020000 + 0x20000 + + + 0 + 0x20040000 + 0x20000 + + + 0 + 0x0 + 0x80000 + + + 0 + 0x1000000 + 0x200000 + + + + + + 1 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 1 + 1 + 1 + 0 + 0 + 0 + + -Wno-documentation -Wno-documentation-unknown-command -Wno-license-management -Wno-missing-noreturn -Wno-missing-prototypes -Wno-missing-variable-declarations -Wno-nonportable-include-path -Wno-packed -Wno-parentheses-equality -Wno-reserved-id-macro -Wno-unused-macros -xc + + + .\RTE\Device\SSE-300-MPS3, ..\..\..\..\..\common\inc, ..\..\inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x00000000 + + ..\CS300_ac6_s.sct + + + --import-cmse-lib-out="..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o" --summary_stderr --info summarysizes --load_addr_map_info --entry=Reset_Handler + + + + + + + + Secure Code + + + main_s.c + 1 + .\main_s.c + + + tx_thread_secure_stack.c + 1 + ..\..\src\tx_thread_secure_stack.c + + + tx_thread_interrupt_disable.S + 2 + ..\..\src\tx_thread_interrupt_disable.S + + + tx_thread_interrupt_restore.S + 2 + ..\..\src\tx_thread_interrupt_restore.S + + + + + Interface + + + interface.c + 1 + .\interface.c + + + + + ::CMSIS + + + ::Device + + + ::Native Driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6_s.sct + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\partition_ARMCM33.h + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c + + + + + + RTE\Device\SSE-300-MPS3\RTE_Device.h + + + + + + + + RTE\Device\SSE-300-MPS3\cmsis_driver_config.h + + + + + + + + RTE\Device\SSE-300-MPS3\device_cfg.h + + + + + + + + RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + + + + + + RTE\Device\SSE-300-MPS3\platform_base_address.h + + + + + + + + RTE\Device\SSE-300-MPS3\region_defs.h + + + + + + + + RTE\Device\SSE-300-MPS3\region_limits.h + + + + + + + + RTE\Device\SSE-300-MPS3\startup_fvp_sse300_mps3.c + + + + + + + + RTE\Device\SSE-300-MPS3\system_SSE300MPS3.c + + + + + + + + RTE\Device\SSE-300-MPS3\system_SSE300MPS3.h + + + + + + + + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.c b/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.c new file mode 100644 index 000000000..4e6e8eeee --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * interface.c Secure/non-secure callable application code + * + * Version 1.0 + * Initial Release + *---------------------------------------------------------------------------*/ + + +#include // CMSE definitions +#include "interface.h" // Header file with secure interface API + +/* typedef for non-secure callback functions */ +typedef funcptr funcptr_NS __attribute__((cmse_nonsecure_call)); + +/* Non-secure callable (entry) function */ +int func1(int x) __attribute__((cmse_nonsecure_entry)) { + return x+3; +} + +/* Non-secure callable (entry) function, calling a non-secure callback function */ +int func2(funcptr callback, int x) __attribute__((cmse_nonsecure_entry)) { + funcptr_NS callback_NS; // non-secure callback function pointer + int y; + + /* return function pointer with cleared LSB */ + callback_NS = (funcptr_NS)cmse_nsfptr_create(callback); + + y = callback_NS (x+1); + + return (y+2); +} diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.h b/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.h new file mode 100644 index 000000000..8215d5a37 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/interface.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * interface.h API definition for the non-secure state + * + * Version 1.0 + * Initial Release + *---------------------------------------------------------------------------*/ + +/* Function pointer declaration */ +typedef int (*funcptr)(int); + +/* Non-secure callable functions */ +extern int func1(int x); +extern int func2(funcptr callback, int x); diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/main_s.c b/ports/cortex_m55/ac6/example_build/demo_secure_zone/main_s.c new file mode 100644 index 000000000..422969de6 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/main_s.c @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2013-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------- + * + * $Date: 15. October 2016 + * $Revision: 1.1.0 + * + * Project: TrustZone for ARMv8-M + * Title: Code template for secure main function + * + *---------------------------------------------------------------------------*/ + +#include "region_limits.h" + +#include "RTE_Components.h" +#include CMSIS_device_header + +/* TZ_START_NS: Start address of non-secure application */ +#ifndef TZ_START_NS +#define TZ_START_NS 0x00080000U +#endif + +/* typedef for non-secure callback functions */ +typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call)); + +/* Secure main() */ +int main(void) { + funcptr_void NonSecure_ResetHandler; + + /* Add user setup code for secure part here*/ + + /* Set non-secure main stack (MSP_NS) */ + __TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS))); + + /* Get non-secure reset handler */ + NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U))); + + /* Start non-secure state software application */ + NonSecure_ResetHandler(); + + /* Non-secure software does not return, this code is not executed */ + while (1) { + __NOP(); + } +} diff --git a/ports/cortex_m55/ac6/example_build/demo_secure_zone/tz_context.c b/ports/cortex_m55/ac6/example_build/demo_secure_zone/tz_context.c new file mode 100644 index 000000000..f31528909 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_secure_zone/tz_context.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2015-2016 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * ---------------------------------------------------------------------------- + * + * $Date: 15. October 2016 + * $Revision: 1.1.0 + * + * Project: TrustZone for ARMv8-M + * Title: Context Management for ARMv8-M TrustZone - Sample implementation + * + *---------------------------------------------------------------------------*/ + +#include "RTE_Components.h" +#include CMSIS_device_header +#include "tz_context.h" + +/// Number of process slots (threads may call secure library code) +#ifndef TZ_PROCESS_STACK_SLOTS +#define TZ_PROCESS_STACK_SLOTS 8U +#endif + +/// Stack size of the secure library code +#ifndef TZ_PROCESS_STACK_SIZE +#define TZ_PROCESS_STACK_SIZE 256U +#endif + +typedef struct { + uint32_t sp_top; // stack space top + uint32_t sp_limit; // stack space limit + uint32_t sp; // current stack pointer +} stack_info_t; + +static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS]; +static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U]; +static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU; + + +/// Initialize secure context memory system +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_InitContextSystem_S (void) { + uint32_t n; + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) { + ProcessStackInfo[n].sp = 0U; + ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n]; + ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE; + *((uint32_t *)ProcessStackMemory[n]) = n + 1U; + } + *((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU; + + ProcessStackFreeSlot = 0U; + + // Default process stack pointer and stack limit + __set_PSPLIM((uint32_t)ProcessStackMemory); + __set_PSP ((uint32_t)ProcessStackMemory); + + // Privileged Thread Mode using PSP + __set_CONTROL(0x02U); + + return 1U; // Success +} + + +/// Allocate context memory for calling secure software modules in TrustZone +/// \param[in] module identifies software modules called from non-secure mode +/// \return value != 0 id TrustZone memory slot identifier +/// \return value 0 no memory available or internal error +__attribute__((cmse_nonsecure_entry)) +TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) { + uint32_t slot; + + (void)module; // Ignore (fixed Stack size) + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + if (ProcessStackFreeSlot == 0xFFFFFFFFU) { + return 0U; // No slot available + } + + slot = ProcessStackFreeSlot; + ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]); + + ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top; + + return (slot + 1U); +} + + +/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) { + uint32_t slot; + + if (__get_IPSR() == 0U) { + return 0U; // Thread Mode + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + ProcessStackInfo[slot].sp = 0U; + + *((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot; + ProcessStackFreeSlot = slot; + + return 1U; // Success +} + + +/// Load secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) { + uint32_t slot; + + if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { + return 0U; // Thread Mode or using Main Stack for threads + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + + // Setup process stack pointer and stack limit + __set_PSPLIM(ProcessStackInfo[slot].sp_limit); + __set_PSP (ProcessStackInfo[slot].sp); + + return 1U; // Success +} + + +/// Store secure context (called on RTOS thread context switch) +/// \param[in] id TrustZone memory slot identifier +/// \return execution status (1: success, 0: error) +__attribute__((cmse_nonsecure_entry)) +uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) { + uint32_t slot; + uint32_t sp; + + if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) { + return 0U; // Thread Mode or using Main Stack for threads + } + + if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) { + return 0U; // Invalid ID + } + + slot = id - 1U; + + if (ProcessStackInfo[slot].sp == 0U) { + return 0U; // Inactive slot + } + + sp = __get_PSP(); + if ((sp < ProcessStackInfo[slot].sp_limit) || + (sp > ProcessStackInfo[slot].sp_top)) { + return 0U; // SP out of range + } + ProcessStackInfo[slot].sp = sp; + + // Default process stack pointer and stack limit + __set_PSPLIM((uint32_t)ProcessStackMemory); + __set_PSP ((uint32_t)ProcessStackMemory); + + return 1U; // Success +} diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h new file mode 100644 index 000000000..5bf4c867c --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/RTE_Device.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __RTE_DEVICE_H +#define __RTE_DEVICE_H + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART0] +// Configuration settings for Driver_USART0 in component ::Drivers:USART +#define RTE_USART0 1 + +// USART (Universal synchronous - asynchronous receiver transmitter) [Driver_USART1] +// Configuration settings for Driver_USART1 in component ::Drivers:USART +#define RTE_USART1 1 + +// MPC (Memory Protection Controller) [Driver_ISRAM0_MPC] +// Configuration settings for Driver_ISRAM0_MPC in component ::Drivers:MPC +#define RTE_ISRAM0_MPC 1 + +// MPC (Memory Protection Controller) [Driver_ISRAM1_MPC] +// Configuration settings for Driver_ISRAM1_MPC in component ::Drivers:MPC +#define RTE_ISRAM1_MPC 1 + +// MPC (Memory Protection Controller) [Driver_SRAM_MPC] +// Configuration settings for Driver_SRAM_MPC in component ::Drivers:MPC +#define RTE_SRAM_MPC 1 + +// MPC (Memory Protection Controller) [Driver_QSPI_MPC] +// Configuration settings for Driver_QSPI_MPC in component ::Drivers:MPC +#define RTE_QSPI_MPC 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN0] +// Configuration settings for Driver_PPC_SSE300_MAIN0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP0] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_MAIN_EXP1] +// Configuration settings for Driver_PPC_SSE300_MAIN_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_MAIN_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH0] +// Configuration settings for Driver_PPC_SSE300_PERIPH0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH1] +// Configuration settings for Driver_PPC_SSE300_PERIPH1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP0] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP0 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP0 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP1] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP1 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP1 1 + +// PPC (Peripheral Protection Controller) [PPC_SSE300_PERIPH_EXP2] +// Configuration settings for Driver_PPC_SSE300_PERIPH_EXP2 in component ::Drivers:PPC +#define RTE_PPC_SSE300_PERIPH_EXP2 1 + +// Flash device emulated by SRAM [Driver_Flash0] +// Configuration settings for Driver_Flash0 in component ::Drivers:Flash +#define RTE_FLASH0 1 + +// I2C SBCon [Driver_I2C0] +// Configuration settings for Driver_I2C0 in component ::Drivers:I2C +#define RTE_I2C0 1 + +#endif /* __RTE_DEVICE_H */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h new file mode 100644 index 000000000..bfc348f47 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/cmsis_driver_config.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_DRIVER_CONFIG_H__ +#define __CMSIS_DRIVER_CONFIG_H__ + +#include "system_SSE300MPS3.h" +#include "device_cfg.h" +#include "device_definition.h" +#include "platform_base_address.h" + +#endif /* __CMSIS_DRIVER_CONFIG_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h new file mode 100644 index 000000000..2ff3eaa77 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/device_cfg.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2020-2022 Arm Limited. All rights reserved. + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEVICE_CFG_H__ +#define __DEVICE_CFG_H__ + +/** + * \file device_cfg.h + * \brief Configuration file native driver re-targeting + * + * \details This file can be used to add native driver specific macro + * definitions to select which peripherals are available in the build. + * + * This is a default device configuration file with all peripherals enabled. + */ + +/* Secure only peripheral configuration */ + +/* ARM MPS3 IO SCC */ +#define MPS3_IO_S +#define MPS3_IO_DEV MPS3_IO_DEV_S + +/* I2C_SBCon */ +#define I2C0_SBCON_S +#define I2C0_SBCON_DEV I2C0_SBCON_DEV_S + +/* I2S */ +#define MPS3_I2S_S +#define MPS3_I2S_DEV MPS3_I2S_DEV_S + +/* ARM UART Controller PL011 */ +#define UART0_CMSDK_S +#define UART0_CMSDK_DEV UART0_CMSDK_DEV_S +#define UART1_CMSDK_S +#define UART1_CMSDK_DEV UART1_CMSDK_DEV_S + +#define DEFAULT_UART_BAUDRATE 115200U + +/* To be used as CODE and DATA sram */ +#define MPC_ISRAM0_S +#define MPC_ISRAM0_DEV MPC_ISRAM0_DEV_S + +#define MPC_ISRAM1_S +#define MPC_ISRAM1_DEV MPC_ISRAM0_DEV_S + +#define MPC_SRAM_S +#define MPC_SRAM_DEV MPC_SRAM_DEV_S + +#define MPC_QSPI_S +#define MPC_QSPI_DEV MPC_QSPI_DEV_S + +/** System Counter Armv8-M */ +#define SYSCOUNTER_CNTRL_ARMV8_M_S +#define SYSCOUNTER_CNTRL_ARMV8_M_DEV SYSCOUNTER_CNTRL_ARMV8_M_DEV_S + +#define SYSCOUNTER_READ_ARMV8_M_S +#define SYSCOUNTER_READ_ARMV8_M_DEV SYSCOUNTER_READ_ARMV8_M_DEV_S +/** + * Arbitrary scaling values for test purposes + */ +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE0_FRACT 0u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_INT 1u +#define SYSCOUNTER_ARMV8_M_DEFAULT_SCALE1_FRACT 0u + +/* System timer */ +#define SYSTIMER0_ARMV8_M_S +#define SYSTIMER0_ARMV8_M_DEV SYSTIMER0_ARMV8_M_DEV_S +#define SYSTIMER1_ARMV8_M_S +#define SYSTIMER1_ARMV8_M_DEV SYSTIMER1_ARMV8_M_DEV_S +#define SYSTIMER2_ARMV8_M_S +#define SYSTIMER2_ARMV8_M_DEV SYSTIMER2_ARMV8_M_DEV_S +#define SYSTIMER3_ARMV8_M_S +#define SYSTIMER3_ARMV8_M_DEV SYSTIMER3_ARMV8_M_DEV_S + +#define SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER2_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) +#define SYSTIMER3_ARMV8M_DEFAULT_FREQ_HZ (25000000ul) + +/* CMSDK GPIO driver structures */ +#define GPIO0_CMSDK_S +#define GPIO0_CMSDK_DEV GPIO0_CMSDK_DEV_S +#define GPIO1_CMSDK_S +#define GPIO1_CMSDK_DEV GPIO1_CMSDK_DEV_S +#define GPIO2_CMSDK_S +#define GPIO2_CMSDK_DEV GPIO2_CMSDK_DEV_S +#define GPIO3_CMSDK_S +#define GPIO3_CMSDK_DEV GPIO3_CMSDK_DEV_S + +/* System Watchdogs */ +#define SYSWDOG_ARMV8_M_S +#define SYSWDOG_ARMV8_M_DEV SYSWDOG_ARMV8_M_DEV_S + +/* ARM MPC SIE 300 driver structures */ +#define MPC_VM0_S +#define MPC_VM0_DEV MPC_VM0_DEV_S +#define MPC_VM1_S +#define MPC_VM1_DEV MPC_VM1_DEV_S +#define MPC_SSRAM2_S +#define MPC_SSRAM2_DEV MPC_SSRAM2_DEV_S +#define MPC_SSRAM3_S +#define MPC_SSRAM3_DEV MPC_SSRAM3_DEV_S + +/* ARM PPC driver structures */ +#define PPC_SSE300_MAIN0_S +#define PPC_SSE300_MAIN0_DEV PPC_SSE300_MAIN0_DEV_S +#define PPC_SSE300_MAIN_EXP0_S +#define PPC_SSE300_MAIN_EXP0_DEV PPC_SSE300_MAIN_EXP0_DEV_S +#define PPC_SSE300_MAIN_EXP1_S +#define PPC_SSE300_MAIN_EXP1_DEV PPC_SSE300_MAIN_EXP1_DEV_S +#define PPC_SSE300_MAIN_EXP2_S +#define PPC_SSE300_MAIN_EXP2_DEV PPC_SSE300_MAIN_EXP2_DEV_S +#define PPC_SSE300_MAIN_EXP3_S +#define PPC_SSE300_MAIN_EXP3_DEV PPC_SSE300_MAIN_EXP3_DEV_S +#define PPC_SSE300_PERIPH0_S +#define PPC_SSE300_PERIPH0_DEV PPC_SSE300_PERIPH0_DEV_S +#define PPC_SSE300_PERIPH1_S +#define PPC_SSE300_PERIPH1_DEV PPC_SSE300_PERIPH1_DEV_S +#define PPC_SSE300_PERIPH_EXP0_S +#define PPC_SSE300_PERIPH_EXP0_DEV PPC_SSE300_PERIPH_EXP0_DEV_S +#define PPC_SSE300_PERIPH_EXP1_S +#define PPC_SSE300_PERIPH_EXP1_DEV PPC_SSE300_PERIPH_EXP1_DEV_S +#define PPC_SSE300_PERIPH_EXP2_S +#define PPC_SSE300_PERIPH_EXP2_DEV PPC_SSE300_PERIPH_EXP2_DEV_S +#define PPC_SSE300_PERIPH_EXP3_S +#define PPC_SSE300_PERIPH_EXP3_DEV PPC_SSE300_PERIPH_EXP3_DEV_S + +/* ARM SPI PL022 */ +/* Invalid device stubs are not defined */ +#define DEFAULT_SPI_SPEED_HZ 4000000U /* 4MHz */ +#define SPI1_PL022_S +#define SPI1_PL022_DEV SPI1_PL022_DEV_S + + +#endif /* __DEVICE_CFG_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct new file mode 100644 index 000000000..343c63d26 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/fvp_sse300_mps3_s.sct @@ -0,0 +1,78 @@ +#! armclang --target=arm-arm-none-eabi -march=armv8.1-m.main -E -xc + +;/* +; * Copyright (c) 2018-2021 Arm Limited. All rights reserved. +; * +; * Licensed under the Apache License, Version 2.0 (the "License"); +; * you may not use this file except in compliance with the License. +; * You may obtain a copy of the License at +; * +; * http://www.apache.org/licenses/LICENSE-2.0 +; * +; * Unless required by applicable law or agreed to in writing, software +; * distributed under the License is distributed on an "AS IS" BASIS, +; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; * See the License for the specific language governing permissions and +; * limitations under the License. +; * +; */ + +#include "region_defs.h" + +LR_CODE S_CODE_START { + ER_CODE S_CODE_START { + *.o (RESET +First) + .ANY (+RO) + } + + /* + * Place the CMSE Veneers (containing the SG instruction) after the code, in + * a separate 32 bytes aligned region so that the SAU can programmed to just + * set this region as Non-Secure Callable. The maximum size of this + * executable region makes it only used the space left over by the ER_CODE + * region so that you can rely on code+veneer size combined will not exceed + * the S_CODE_SIZE value. We also substract from the available space the + * area used to align this section on 32 bytes boundary (for SAU conf). + */ + ER_CODE_CMSE_VENEER +0 ALIGN 32 { + *(Veneer$$CMSE) + } + /* + * This dummy region ensures that the next one will be aligned on a 32 bytes + * boundary, so that the following region will not be mistakenly configured + * as Non-Secure Callable by the SAU. + */ + ER_CODE_CMSE_VENEER_DUMMY +0 ALIGN 32 EMPTY 0 {} + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + CODE_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(CODE_WATERMARK) <= S_CODE_START + S_CODE_SIZE) + + ER_DATA S_DATA_START { + .ANY (+ZI +RW) + } + + #if HEAP_SIZE > 0 + ARM_LIB_HEAP +0 ALIGN 8 EMPTY HEAP_SIZE { ; Reserve empty region for heap + } + #endif + + ARM_LIB_STACK +0 ALIGN 32 EMPTY STACK_SIZE { ; Reserve empty region for stack + } + + /* This empty, zero long execution region is here to mark the limit address + * of the last execution region that is allocated in SRAM. + */ + SRAM_WATERMARK +0 EMPTY 0x0 { + } + /* Make sure that the sections allocated in the SRAM does not exceed the + * size of the SRAM available. + */ + ScatterAssert(ImageLimit(SRAM_WATERMARK) <= S_DATA_START + S_DATA_SIZE) +} diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h new file mode 100644 index 000000000..b813097f5 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/platform_base_address.h @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2019-2021 Arm Limited + * + * Licensed under the Apache License Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * \file platform_base_address.h + * \brief This file defines all the peripheral base addresses for AN552 MPS3 SSE-300 + + * Ethos-U55 platform. + */ + +#ifndef __PLATFORM_BASE_ADDRESS_H__ +#define __PLATFORM_BASE_ADDRESS_H__ + +/* ======= Defines peripherals memory map addresses ======= */ +/* Non-secure memory map addresses */ +#define ITCM_BASE_NS 0x00000000 /* Instruction TCM Non-Secure base address */ +#define SRAM_BASE_NS 0x01000000 /* CODE SRAM Non-Secure base address */ +#define DTCM0_BASE_NS 0x20000000 /* Data TCM block 0 Non-Secure base address */ +#define DTCM1_BASE_NS 0x20020000 /* Data TCM block 1 Non-Secure base address */ +#define DTCM2_BASE_NS 0x20040000 /* Data TCM block 2 Non-Secure base address */ +#define DTCM3_BASE_NS 0x20060000 /* Data TCM block 3 Non-Secure base address */ +#define ISRAM0_BASE_NS 0x21000000 /* Internal SRAM Area Non-Secure base address */ +#define ISRAM1_BASE_NS 0x21100000 /* Internal SRAM Area Non-Secure base address */ +#define QSPI_SRAM_BASE_NS 0x28000000 /* QSPI SRAM Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define CPU0_PWRCTRL_BASE_NS 0x40012000 /* CPU 0 Power Control Block Non-Secure base address */ +#define CPU0_IDENTITY_BASE_NS 0x4001F000 /* CPU 0 Identity Block Non-Secure base address */ +#define SSE300_NSACFG_BASE_NS 0x40080000 /* SSE-300 Non-Secure Access Configuration Register Block Non-Secure base address */ +/* Non-Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_NS 0x41100000 /* GPIO 0 Non-Secure base address */ +#define GPIO1_CMSDK_BASE_NS 0x41101000 /* GPIO 1 Non-Secure base address */ +#define GPIO2_CMSDK_BASE_NS 0x41102000 /* GPIO 2 Non-Secure base address */ +#define GPIO3_CMSDK_BASE_NS 0x41103000 /* GPIO 3 Non-Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_NS 0x41104000 /* FMC CMSDK GPIO 0 Non-Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_NS 0x41105000 /* FMC CMSDK GPIO 1 Non-Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_NS 0x41106000 /* FMC CMSDK GPIO 2 Non-Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_NS 0x41107000 /* FMC CMSDK GPIO 3 Non-Secure base address */ +#define EXTERNAL_MANAGER_0_BASE_NS 0x41200000 /* External manager 0 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_1_BASE_NS 0x41201000 /* External manager 1 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_2_BASE_NS 0x41202000 /* External manager 2 (Unused) Non-Secure base address */ +#define EXTERNAL_MANAGER_3_BASE_NS 0x41203000 /* External manager 3 (Unused) Non-Secure base address */ +#define ETHERNET_BASE_NS 0x41400000 /* Ethernet Non-Secure base address */ +#define USB_BASE_NS 0x41500000 /* USB Non-Secure base address */ +#define USER_APB0_BASE_NS 0x41700000 /* User APB 0 Non-Secure base address */ +#define USER_APB1_BASE_NS 0x41701000 /* User APB 1 Non-Secure base address */ +#define USER_APB2_BASE_NS 0x41702000 /* User APB 2 Non-Secure base address */ +#define USER_APB3_BASE_NS 0x41703000 /* User APB 3 Non-Secure base address */ +#define QSPI_CONFIG_BASE_NS 0x41800000 /* QSPI Config Non-Secure base address */ +#define QSPI_WRITE_BASE_NS 0x41801000 /* QSPI Write Non-Secure base address */ +/* Non-Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_NS 0x48000000 /* System Timer 0 Non-Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_NS 0x48001000 /* System Timer 1 Non-Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_NS 0x48002000 /* System Timer 2 Non-Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_NS 0x48003000 /* System Timer 3 Non-Secure base address */ +#define SSE300_SYSINFO_BASE_NS 0x48020000 /* SSE-300 System info Block Non-Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_NS 0x4802F000 /* CMSDK based SLOWCLK Timer Non-Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_NS 0x48040000 /* Non-Secure Watchdog Timer control frame Non-Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_NS 0x48041000 /* Non-Secure Watchdog Timer refresh frame Non-Secure base address */ +#define SYSCNTR_READ_BASE_NS 0x48101000 /* System Counter Read Secure base address */ +/* Non-Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_NS 0x48102000 /* Ethos-U55 APB Non-Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_NS 0x48103000 /* Ethos-U55 Timing Adapter 0 APB registers Non-Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_NS 0x48103200 /* Ethos-U55 Timing Adapter 1 APB registers Non-Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_NS 0x49200000 /* FPGA - SBCon I2C (Touch) Non-Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_NS 0x49201000 /* FPGA - SBCon I2C (Audio Conf) Non-Secure base address */ +#define FPGA_SPI_ADC_BASE_NS 0x49202000 /* FPGA - PL022 (SPI ADC) Non-Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_NS 0x49203000 /* FPGA - PL022 (SPI Shield0) Non-Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_NS 0x49204000 /* FPGA - PL022 (SPI Shield1) Non-Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_NS 0x49205000 /* SBCon (I2C - Shield0) Non-Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_NS 0x49206000 /* SBCon (I2C – Shield1) Non-Secure base address */ +#define USER_APB_BASE_NS 0x49207000 /* USER APB Non-Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_NS 0x49208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Non-Secure base address */ +#define FMC_USER_APB0 0x4920C000 /* FMC User APB0 */ +#define FMC_USER_APB1 0x4920D000 /* FMC User APB1 */ +#define FMC_USER_APB2 0x4920E000 /* FMC User APB2 */ +#define FMC_USER_APB3 0x4920F000 /* FMC User APB3 */ +#define FPGA_SCC_BASE_NS 0x49300000 /* FPGA - SCC registers Non-Secure base address */ +#define FPGA_I2S_BASE_NS 0x49301000 /* FPGA - I2S (Audio) Non-Secure base address */ +#define FPGA_IO_BASE_NS 0x49302000 /* FPGA - IO (System Ctrl + I/O) Non-Secure base address */ +#define UART0_BASE_NS 0x49303000 /* UART 0 Non-Secure base address */ +#define UART1_BASE_NS 0x49304000 /* UART 1 Non-Secure base address */ +#define UART2_BASE_NS 0x49305000 /* UART 2 Non-Secure base address */ +#define UART3_BASE_NS 0x49306000 /* UART 3 Non-Secure base address */ +#define UART4_BASE_NS 0x49307000 /* UART 4 Non-Secure base address */ +#define UART5_BASE_NS 0x49308000 /* UART 5 Non-Secure base address */ +#define CLCD_Config_Reg_BASE_NS 0x4930A000 /* CLCD Config Reg Non-Secure base address */ +#define RTC_BASE_NS 0x4930B000 /* RTC Non-Secure base address */ +#define DDR4_BLK0_BASE_NS 0x60000000 /* DDR4 block 0 Non-Secure base address */ +#define DDR4_BLK2_BASE_NS 0x80000000 /* DDR4 block 2 Non-Secure base address */ +#define DDR4_BLK4_BASE_NS 0xA0000000 /* DDR4 block 4 Non-Secure base address */ +#define DDR4_BLK6_BASE_NS 0xC0000000 /* DDR4 block 6 Non-Secure base address */ + +/* Secure memory map addresses */ +#define ITCM_BASE_S 0x10000000 /* Instruction TCM Secure base address */ +#define SRAM_BASE_S 0x11000000 /* CODE SRAM Secure base address */ +#define DTCM0_BASE_S 0x30000000 /* Data TCM block 0 Secure base address */ +#define DTCM1_BASE_S 0x30020000 /* Data TCM block 1 Secure base address */ +#define DTCM2_BASE_S 0x30040000 /* Data TCM block 2 Secure base address */ +#define DTCM3_BASE_S 0x30060000 /* Data TCM block 3 Secure base address */ +#define ISRAM0_BASE_S 0x31000000 /* Internal SRAM Area Secure base address */ +#define ISRAM1_BASE_S 0x31100000 /* Internal SRAM Area Secure base address */ +#define QSPI_SRAM_BASE_S 0x38000000 /* QSPI SRAM Secure base address */ +/* Secure Subsystem peripheral region */ +#define CPU0_SECCTRL_BASE_S 0x50011000 /* CPU 0 Local Security Control Block Secure base address */ +#define CPU0_PWRCTRL_BASE_S 0x50012000 /* CPU 0 Power Control Block Secure base address */ +#define CPU0_IDENTITY_BASE_S 0x5001F000 /* CPU 0 Identity Block Secure base address */ +#define SSE300_SACFG_BASE_S 0x50080000 /* SSE-300 Secure Access Configuration Register Secure base address */ +#define MPC_ISRAM0_BASE_S 0x50083000 /* Internal SRAM0 Memory Protection Controller Secure base address */ +#define MPC_ISRAM1_BASE_S 0x50084000 /* Internal SRAM1 Memory Protection Controller Secure base address */ +/* Secure MSTEXPPILL Peripheral region */ +#define GPIO0_CMSDK_BASE_S 0x51100000 /* GPIO 0 Secure base address */ +#define GPIO1_CMSDK_BASE_S 0x51101000 /* GPIO 1 Secure base address */ +#define GPIO2_CMSDK_BASE_S 0x51102000 /* GPIO 2 Secure base address */ +#define GPIO3_CMSDK_BASE_S 0x51103000 /* GPIO 3 Secure base address */ +#define FMC_CMSDK_GPIO_0_BASE_S 0x51104000 /* FMC CMSDK GPIO 0 Secure base address */ +#define FMC_CMSDK_GPIO_1_BASE_S 0x51105000 /* FMC CMSDK GPIO 1 Secure base address */ +#define FMC_CMSDK_GPIO_2_BASE_S 0x51106000 /* FMC CMSDK GPIO 2 Secure base address */ +#define FMC_CMSDK_GPIO_3_BASE_S 0x51107000 /* FMC CMSDK GPIO 3 Secure base address */ +#define EXTERNAL_MANAGER0_BASE_S 0x51200000 /* External Manager 0 (Unused) Secure base address */ +#define EXTERNAL_MANAGER1_BASE_S 0x51201000 /* External Manager 1 (Unused) Secure base address */ +#define EXTERNAL_MANAGER2_BASE_S 0x51202000 /* External Manager 2 (Unused) Secure base address */ +#define EXTERNAL_MANAGER3_BASE_S 0x51203000 /* External Manager 3 (Unused) Secure base address */ +#define ETHERNET_BASE_S 0x51400000 /* Ethernet Secure base address */ +#define USB_BASE_S 0x51500000 /* USB Secure base address */ +#define USER_APB0_BASE_S 0x51700000 /* User APB 0 Secure base address */ +#define USER_APB1_BASE_S 0x51701000 /* User APB 1 Secure base address */ +#define USER_APB2_BASE_S 0x51702000 /* User APB 2 Secure base address */ +#define USER_APB3_BASE_S 0x51703000 /* User APB 3 Secure base address */ +#define QSPI_CONFIG_BASE_S 0x51800000 /* QSPI Config Secure base address */ +#define QSPI_WRITE_BASE_S 0x51801000 /* QSPI Write Secure base address */ +#define MPC_SRAM_BASE_S 0x57000000 /* SRAM Memory Protection Controller Secure base address */ +#define MPC_QSPI_BASE_S 0x57001000 /* QSPI Memory Protection Controller Secure base address */ +#define MPC_DDR4_BASE_S 0x57002000 /* DDR4 Memory Protection Controller Secure base address */ +/* Secure Subsystem peripheral region */ +#define SYSTIMER0_ARMV8_M_BASE_S 0x58000000 /* System Timer 0 Secure base address */ +#define SYSTIMER1_ARMV8_M_BASE_S 0x58001000 /* System Timer 1 Secure base address */ +#define SYSTIMER2_ARMV8_M_BASE_S 0x58002000 /* System Timer 0 Secure base address */ +#define SYSTIMER3_ARMV8_M_BASE_S 0x58003000 /* System Timer 1 Secure base address */ +#define SSE300_SYSINFO_BASE_S 0x58020000 /* SSE-300 System info Block Secure base address */ +#define SSE300_SYSCTRL_BASE_S 0x58021000 /* SSE-300 System control Block Secure base address */ +#define SSE300_SYSPPU_BASE_S 0x58022000 /* SSE-300 System Power Policy Unit Secure base address */ +#define SSE300_CPU0PPU_BASE_S 0x58023000 /* SSE-300 CPU 0 Power Policy Unit Secure base address */ +#define SSE300_MGMTPPU_BASE_S 0x58028000 /* SSE-300 Management Power Policy Unit Secure base address */ +#define SSE300_DBGPPU_BASE_S 0x58029000 /* SSE-300 Debug Power Policy Unit Secure base address */ +#define SLOWCLK_WDOG_CMSDK_BASE_S 0x5802E000 /* CMSDK based SLOWCLK Watchdog Secure base address */ +#define SLOWCLK_TIMER_CMSDK_BASE_S 0x5802F000 /* CMSDK based SLOWCLK Timer Secure base address */ +#define SYSWDOG_ARMV8_M_CNTRL_BASE_S 0x58040000 /* Secure Watchdog Timer control frame Secure base address */ +#define SYSWDOG_ARMV8_M_REFRESH_BASE_S 0x58041000 /* Secure Watchdog Timer refresh frame Secure base address */ +#define SYSCNTR_CNTRL_BASE_S 0x58100000 /* System Counter Control Secure base address */ +#define SYSCNTR_READ_BASE_S 0x58101000 /* System Counter Read Secure base address */ +/* Secure MSTEXPPIHL Peripheral region */ +#define ETHOS_U55_APB_BASE_S 0x58102000 /* Ethos-U55 APB Secure base address */ +#define U55_TIMING_ADAPTER_0_BASE_S 0x58103000 /* Ethos-U55 Timing Adapter 0 APB registers Secure base address */ +#define U55_TIMING_ADAPTER_1_BASE_S 0x58103200 /* Ethos-U55 Timing Adapter 1 APB registers Secure base address */ +#define FPGA_SBCon_I2C_TOUCH_BASE_S 0x59200000 /* FPGA - SBCon I2C (Touch) Secure base address */ +#define FPGA_SBCon_I2C_AUDIO_BASE_S 0x59201000 /* FPGA - SBCon I2C (Audio Conf) Secure base address */ +#define FPGA_SPI_ADC_BASE_S 0x59202000 /* FPGA - PL022 (SPI ADC) Secure base address */ +#define FPGA_SPI_SHIELD0_BASE_S 0x59203000 /* FPGA - PL022 (SPI Shield0) Secure base address */ +#define FPGA_SPI_SHIELD1_BASE_S 0x59204000 /* FPGA - PL022 (SPI Shield1) Secure base address */ +#define SBCon_I2C_SHIELD0_BASE_S 0x59205000 /* SBCon (I2C - Shield0) Secure base address */ +#define SBCon_I2C_SHIELD1_BASE_S 0x59206000 /* SBCon (I2C – Shield1) Secure base address */ +#define USER_APB_BASE_S 0x59207000 /* USER APB Secure base address */ +#define FPGA_DDR4_EEPROM_BASE_S 0x59208000 /* FPGA - SBCon I2C (DDR4 EEPROM) Secure base address */ +#define FMC_USER_APB_0_BASE_S 0x5920C000 /* FMC User APB0 registers Secure base address */ +#define FMC_USER_APB_1_BASE_S 0x5920D000 /* FMC User APB1 registers Secure base address */ +#define FMC_USER_APB_2_BASE_S 0x5920E000 /* FMC User APB2 registers Secure base address */ +#define FMC_USER_APB_3_BASE_S 0x5920F000 /* FMC User APB3 registers Secure base address */ +#define FPGA_SCC_BASE_S 0x59300000 /* FPGA - SCC registers Secure base address */ +#define FPGA_I2S_BASE_S 0x59301000 /* FPGA - I2S (Audio) Secure base address */ +#define FPGA_IO_BASE_S 0x59302000 /* FPGA - IO (System Ctrl + I/O) Secure base address */ +#define UART0_BASE_S 0x59303000 /* UART 0 Secure base address */ +#define UART1_BASE_S 0x59304000 /* UART 1 Secure base address */ +#define UART2_BASE_S 0x59305000 /* UART 2 Secure base address */ +#define UART3_BASE_S 0x59306000 /* UART 3 Secure base address */ +#define UART4_BASE_S 0x59307000 /* UART 4 Secure base address */ +#define UART5_BASE_S 0x59308000 /* UART 5 Secure base address */ +#define CLCD_Config_Reg_BASE_S 0x5930A000 /* CLCD Config Reg Secure base address */ +#define RTC_BASE_S 0x5930B000 /* RTC Secure base address */ +#define DDR4_BLK1_BASE_S 0x70000000 /* DDR4 block 1 Secure base address */ +#define DDR4_BLK3_BASE_S 0x90000000 /* DDR4 block 3 Secure base address */ +#define DDR4_BLK5_BASE_S 0xB0000000 /* DDR4 block 5 Secure base address */ +#define DDR4_BLK7_BASE_S 0xD0000000 /* DDR4 block 7 Secure base address */ + +/* Memory map addresses exempt from memory attribution by both the SAU and IDAU */ +#define SSE300_EWIC_BASE 0xE0047000 /* External Wakeup Interrupt Controller + * Access from Non-secure software is only allowed + * if AIRCR.BFHFNMINS is set to 1 */ + +/* Memory size definitions */ +#define ITCM_SIZE (0x00080000) /* 512 kB */ +#define DTCM_BLK_SIZE (0x00020000) /* 128 kB */ +#define DTCM_BLK_NUM (0x4) /* Number of DTCM blocks */ +#define SRAM_SIZE (0x00100000) /* 1 MB */ +#define ISRAM0_SIZE (0x00100000) /* 1 MB */ +#define ISRAM1_SIZE (0x00100000) /* 1 MB */ +#define QSPI_SRAM_SIZE (0x00800000) /* 8 MB */ +#define DDR4_BLK_SIZE (0x10000000) /* 256 MB */ +#define DDR4_BLK_NUM (0x8) /* Number of DDR4 blocks */ + +/* Defines for Driver MPC's */ +/* SRAM -- 2 MB */ +#define MPC_SRAM_RANGE_BASE_NS (SRAM_BASE_NS) +#define MPC_SRAM_RANGE_LIMIT_NS (SRAM_BASE_NS + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_NS (0x0) +#define MPC_SRAM_RANGE_BASE_S (SRAM_BASE_S) +#define MPC_SRAM_RANGE_LIMIT_S (SRAM_BASE_S + SRAM_SIZE-1) +#define MPC_SRAM_RANGE_OFFSET_S (0x0) + +/* QSPI -- 8 MB*/ +#define MPC_QSPI_RANGE_BASE_NS (QSPI_SRAM_BASE_NS) +#define MPC_QSPI_RANGE_LIMIT_NS (QSPI_SRAM_BASE_NS + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_NS (0x0) +#define MPC_QSPI_RANGE_BASE_S (QSPI_SRAM_BASE_S) +#define MPC_QSPI_RANGE_LIMIT_S (QSPI_SRAM_BASE_S + QSPI_SRAM_SIZE-1) +#define MPC_QSPI_RANGE_OFFSET_S (0x0) + +/* ISRAM0 -- 2 MB*/ +#define MPC_ISRAM0_RANGE_BASE_NS (ISRAM0_BASE_NS) +#define MPC_ISRAM0_RANGE_LIMIT_NS (ISRAM0_BASE_NS + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM0_RANGE_BASE_S (ISRAM0_BASE_S) +#define MPC_ISRAM0_RANGE_LIMIT_S (ISRAM0_BASE_S + ISRAM0_SIZE-1) +#define MPC_ISRAM0_RANGE_OFFSET_S (0x0) + +/* ISRAM1 -- 2 MB*/ +#define MPC_ISRAM1_RANGE_BASE_NS (ISRAM1_BASE_NS) +#define MPC_ISRAM1_RANGE_LIMIT_NS (ISRAM1_BASE_NS + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_NS (0x0) +#define MPC_ISRAM1_RANGE_BASE_S (ISRAM1_BASE_S) +#define MPC_ISRAM1_RANGE_LIMIT_S (ISRAM1_BASE_S + ISRAM1_SIZE-1) +#define MPC_ISRAM1_RANGE_OFFSET_S (0x0) + +/* DDR4 -- 2GB (8 * 256 MB) */ +#define MPC_DDR4_BLK0_RANGE_BASE_NS (DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK0_RANGE_LIMIT_NS (DDR4_BLK0_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK0_RANGE_OFFSET_NS (0x0) +#define MPC_DDR4_BLK1_RANGE_BASE_S (DDR4_BLK1_BASE_S) +#define MPC_DDR4_BLK1_RANGE_LIMIT_S (DDR4_BLK1_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK1_RANGE_OFFSET_S (DDR4_BLK1_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_BASE_NS (DDR4_BLK2_BASE_NS) +#define MPC_DDR4_BLK2_RANGE_LIMIT_NS (DDR4_BLK2_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK2_RANGE_OFFSET_NS (DDR4_BLK2_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK3_RANGE_BASE_S (DDR4_BLK3_BASE_S) +#define MPC_DDR4_BLK3_RANGE_LIMIT_S (DDR4_BLK3_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK3_RANGE_OFFSET_S (DDR4_BLK3_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_BASE_NS (DDR4_BLK4_BASE_NS) +#define MPC_DDR4_BLK4_RANGE_LIMIT_NS (DDR4_BLK4_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK4_RANGE_OFFSET_NS (DDR4_BLK4_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK5_RANGE_BASE_S (DDR4_BLK5_BASE_S) +#define MPC_DDR4_BLK5_RANGE_LIMIT_S (DDR4_BLK5_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK5_RANGE_OFFSET_S (DDR4_BLK5_BASE_S - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_BASE_NS (DDR4_BLK6_BASE_NS) +#define MPC_DDR4_BLK6_RANGE_LIMIT_NS (DDR4_BLK6_BASE_NS + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK6_RANGE_OFFSET_NS (DDR4_BLK6_BASE_NS - DDR4_BLK0_BASE_NS) +#define MPC_DDR4_BLK7_RANGE_BASE_S (DDR4_BLK7_BASE_S) +#define MPC_DDR4_BLK7_RANGE_LIMIT_S (DDR4_BLK7_BASE_S + ((DDR4_BLK_SIZE)-1)) +#define MPC_DDR4_BLK7_RANGE_OFFSET_S (DDR4_BLK7_BASE_S - DDR4_BLK0_BASE_NS) + +#endif /* __PLATFORM_BASE_ADDRESS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h new file mode 100644 index 000000000..32ac16b37 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_defs.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016-2022 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_DEFS_H__ +#define __REGION_DEFS_H__ + +#include "region_limits.h" + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure regions */ +#define S_CODE_START ( S_ROM_ALIAS ) +#define S_CODE_SIZE ( TOTAL_S_ROM_SIZE ) +#define S_CODE_LIMIT ( S_CODE_START + S_CODE_SIZE ) + +#define S_DATA_START ( S_RAM_ALIAS ) +#define S_DATA_SIZE ( TOTAL_S_RAM_SIZE ) +#define S_DATA_LIMIT ( S_DATA_START + S_DATA_SIZE ) + +#define S_DDR4_START ( S_DDR4_ALIAS ) +#define S_DDR4_SIZE ( TOTAL_S_DDR4_SIZE ) +#define S_DDR4_LIMIT ( S_DDR4_START + S_DDR4_SIZE ) + +#endif /* __REGION_DEFS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h new file mode 100644 index 000000000..e7897866a --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/region_limits.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018-2022 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __REGION_LIMITS_H__ +#define __REGION_LIMITS_H__ + +/* ************************************************************** + * WARNING: this file is parsed both by the C/C++ compiler + * and the linker. As a result the syntax must be valid not only + * for C/C++ but for the linker scripts too. + * Beware of the following limitations: + * - LD (GCC linker) requires white space around operators. + * - UL postfix for macros is not suported by the linker script + ****************************************************************/ + +/* Secure Code */ +#define S_ROM_ALIAS (0x10000000) /* ITCM_BASE_S */ +#define TOTAL_S_ROM_SIZE (0x00080000) /* 512 kB */ + +/* Secure Data */ +#define S_RAM_ALIAS (0x30000000) /* DTCM_BASE_S */ +#define TOTAL_S_RAM_SIZE (0x00080000) /* 512 kB */ + +/* Secure DDR4 */ +#define S_DDR4_ALIAS (0x70000000) /* DDR4_BLK1_BASE_S */ +#define TOTAL_S_DDR4_SIZE (0x10000000) /* 256 MB */ + +/* Heap and Stack sizes for secure and nonsecure applications */ +#define HEAP_SIZE (0x00000400) /* 1 KiB */ +#define STACK_SIZE (0x00000400) /* 1 KiB */ + +#endif /* __REGION_LIMITS_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c new file mode 100644 index 000000000..d1e59d74a --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/startup_fvp_sse300_mps3.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2009-2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 startup_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "SSE300MPS3.h" + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler Function Prototype + *----------------------------------------------------------------------------*/ +typedef void( *pFunc )( void ); + +/*---------------------------------------------------------------------------- + External References + *----------------------------------------------------------------------------*/ +extern uint32_t __INITIAL_SP; +extern uint32_t __STACK_LIMIT; + +extern void __PROGRAM_START(void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Internal References + *----------------------------------------------------------------------------*/ +void Reset_Handler (void) __NO_RETURN; + +/*---------------------------------------------------------------------------- + Exception / Interrupt Handler + *----------------------------------------------------------------------------*/ +#define DEFAULT_IRQ_HANDLER(handler_name) \ +void __WEAK __NO_RETURN handler_name(void); \ +void handler_name(void) { \ + while(1); \ +} + +/* Exceptions */ +DEFAULT_IRQ_HANDLER(NMI_Handler) +DEFAULT_IRQ_HANDLER(HardFault_Handler) +DEFAULT_IRQ_HANDLER(MemManage_Handler) +DEFAULT_IRQ_HANDLER(BusFault_Handler) +DEFAULT_IRQ_HANDLER(UsageFault_Handler) +DEFAULT_IRQ_HANDLER(SecureFault_Handler) +DEFAULT_IRQ_HANDLER(SVC_Handler) +DEFAULT_IRQ_HANDLER(DebugMon_Handler) +DEFAULT_IRQ_HANDLER(PendSV_Handler) +DEFAULT_IRQ_HANDLER(SysTick_Handler) + +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_RESET_Handler) +DEFAULT_IRQ_HANDLER(NONSEC_WATCHDOG_Handler) +DEFAULT_IRQ_HANDLER(SLOWCLK_Timer_Handler) +DEFAULT_IRQ_HANDLER(TIMER0_Handler) +DEFAULT_IRQ_HANDLER(TIMER1_Handler) +DEFAULT_IRQ_HANDLER(TIMER2_Handler) +DEFAULT_IRQ_HANDLER(MPC_Handler) +DEFAULT_IRQ_HANDLER(PPC_Handler) +DEFAULT_IRQ_HANDLER(MSC_Handler) +DEFAULT_IRQ_HANDLER(BRIDGE_ERROR_Handler) +DEFAULT_IRQ_HANDLER(MGMT_PPU_Handler) +DEFAULT_IRQ_HANDLER(SYS_PPU_Handler) +DEFAULT_IRQ_HANDLER(CPU0_PPU_Handler) +DEFAULT_IRQ_HANDLER(DEBUG_PPU_Handler) +DEFAULT_IRQ_HANDLER(TIMER3_Handler) +DEFAULT_IRQ_HANDLER(CTI_REQ0_IRQHandler) +DEFAULT_IRQ_HANDLER(CTI_REQ1_IRQHandler) + +DEFAULT_IRQ_HANDLER(System_Timestamp_Counter_Handler) +DEFAULT_IRQ_HANDLER(UARTRX0_Handler) +DEFAULT_IRQ_HANDLER(UARTTX0_Handler) +DEFAULT_IRQ_HANDLER(UARTRX1_Handler) +DEFAULT_IRQ_HANDLER(UARTTX1_Handler) +DEFAULT_IRQ_HANDLER(UARTRX2_Handler) +DEFAULT_IRQ_HANDLER(UARTTX2_Handler) +DEFAULT_IRQ_HANDLER(UARTRX3_Handler) +DEFAULT_IRQ_HANDLER(UARTTX3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX4_Handler) +DEFAULT_IRQ_HANDLER(UARTTX4_Handler) +DEFAULT_IRQ_HANDLER(UART0_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART1_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART2_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART3_Combined_Handler) +DEFAULT_IRQ_HANDLER(UART4_Combined_Handler) +DEFAULT_IRQ_HANDLER(UARTOVF_Handler) +DEFAULT_IRQ_HANDLER(ETHERNET_Handler) +DEFAULT_IRQ_HANDLER(I2S_Handler) +DEFAULT_IRQ_HANDLER(TOUCH_SCREEN_Handler) +DEFAULT_IRQ_HANDLER(USB_Handler) +DEFAULT_IRQ_HANDLER(SPI_ADC_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD0_Handler) +DEFAULT_IRQ_HANDLER(SPI_SHIELD1_Handler) +DEFAULT_IRQ_HANDLER(ETHOS_U55_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_Combined_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO0_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO1_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_3_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_4_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_5_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_6_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_7_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_8_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_9_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_10_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_11_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_12_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_13_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_14_Handler) +DEFAULT_IRQ_HANDLER(GPIO2_15_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_0_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_1_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_2_Handler) +DEFAULT_IRQ_HANDLER(GPIO3_3_Handler) +DEFAULT_IRQ_HANDLER(UARTRX5_Handler) +DEFAULT_IRQ_HANDLER(UARTTX5_Handler) +DEFAULT_IRQ_HANDLER(UART5_Handler) + +/*---------------------------------------------------------------------------- + Exception / Interrupt Vector table + *----------------------------------------------------------------------------*/ + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#endif + +extern const pFunc __VECTOR_TABLE[496]; + const pFunc __VECTOR_TABLE[496] __VECTOR_TABLE_ATTRIBUTE = { + (pFunc)(&__INITIAL_SP), /* Initial Stack Pointer */ + Reset_Handler, /* Reset Handler */ + NMI_Handler, /* -14: NMI Handler */ + HardFault_Handler, /* -13: Hard Fault Handler */ + MemManage_Handler, /* -12: MPU Fault Handler */ + BusFault_Handler, /* -11: Bus Fault Handler */ + UsageFault_Handler, /* -10: Usage Fault Handler */ + SecureFault_Handler, /* -9: Secure Fault Handler */ + 0, /* Reserved */ + 0, /* Reserved */ + 0, /* Reserved */ + SVC_Handler, /* -5: SVCall Handler */ + DebugMon_Handler, /* -4: Debug Monitor Handler */ + 0, /* Reserved */ + PendSV_Handler, /* -2: PendSV Handler */ + SysTick_Handler, /* -1: SysTick Handler */ + + NONSEC_WATCHDOG_RESET_Handler, /* 0: Non-Secure Watchdog Reset Handler */ + NONSEC_WATCHDOG_Handler, /* 1: Non-Secure Watchdog Handler */ + SLOWCLK_Timer_Handler, /* 2: SLOWCLK Timer Handler */ + TIMER0_Handler, /* 3: TIMER 0 Handler */ + TIMER1_Handler, /* 4: TIMER 1 Handler */ + TIMER2_Handler, /* 5: TIMER 2 Handler */ + 0, /* 6: Reserved */ + 0, /* 7: Reserved */ + 0, /* 8: Reserved */ + MPC_Handler, /* 9: MPC Combined (Secure) Handler */ + PPC_Handler, /* 10: PPC Combined (Secure) Handler */ + MSC_Handler, /* 11: MSC Combined (Secure) Handler */ + BRIDGE_ERROR_Handler, /* 12: Bridge Error (Secure) Handler */ + 0, /* 13: Reserved */ + MGMT_PPU_Handler, /* 14: MGMT PPU Handler */ + SYS_PPU_Handler, /* 15: SYS PPU Handler */ + CPU0_PPU_Handler, /* 16: CPU0 PPU Handler */ + 0, /* 17: Reserved */ + 0, /* 18: Reserved */ + 0, /* 19: Reserved */ + 0, /* 20: Reserved */ + 0, /* 21: Reserved */ + 0, /* 22: Reserved */ + 0, /* 23: Reserved */ + 0, /* 24: Reserved */ + 0, /* 25: Reserved */ + DEBUG_PPU_Handler, /* 26: DEBUG PPU Handler */ + TIMER3_Handler, /* 27: TIMER 3 Handler */ + CTI_REQ0_IRQHandler, /* 28: CTI request 0 IRQ Handler */ + CTI_REQ1_IRQHandler, /* 29: CTI request 1 IRQ Handler */ + 0, /* 30: Reserved */ + 0, /* 31: Reserved */ + + /* External interrupts */ + System_Timestamp_Counter_Handler, /* 32: System timestamp counter Handler */ + UARTRX0_Handler, /* 33: UART 0 RX Handler */ + UARTTX0_Handler, /* 34: UART 0 TX Handler */ + UARTRX1_Handler, /* 35: UART 1 RX Handler */ + UARTTX1_Handler, /* 36: UART 1 TX Handler */ + UARTRX2_Handler, /* 37: UART 2 RX Handler */ + UARTTX2_Handler, /* 38: UART 2 TX Handler */ + UARTRX3_Handler, /* 39: UART 3 RX Handler */ + UARTTX3_Handler, /* 40: UART 3 TX Handler */ + UARTRX4_Handler, /* 41: UART 4 RX Handler */ + UARTTX4_Handler, /* 42: UART 4 TX Handler */ + UART0_Combined_Handler, /* 43: UART 0 Combined Handler */ + UART1_Combined_Handler, /* 44: UART 1 Combined Handler */ + UART2_Combined_Handler, /* 45: UART 2 Combined Handler */ + UART3_Combined_Handler, /* 46: UART 3 Combined Handler */ + UART4_Combined_Handler, /* 47: UART 4 Combined Handler */ + UARTOVF_Handler, /* 48: UART 0, 1, 2, 3, 4 & 5 Overflow Handler */ + ETHERNET_Handler, /* 49: Ethernet Handler */ + I2S_Handler, /* 50: Audio I2S Handler */ + TOUCH_SCREEN_Handler, /* 51: Touch Screen Handler */ + USB_Handler, /* 52: USB Handler */ + SPI_ADC_Handler, /* 53: SPI ADC Handler */ + SPI_SHIELD0_Handler, /* 54: SPI (Shield 0) Handler */ + SPI_SHIELD1_Handler, /* 55: SPI (Shield 0) Handler */ + ETHOS_U55_Handler, /* 56: Ethos-U55 Handler */ + 0, /* 57: Reserved */ + 0, /* 58: Reserved */ + 0, /* 59: Reserved */ + 0, /* 60: Reserved */ + 0, /* 61: Reserved */ + 0, /* 62: Reserved */ + 0, /* 63: Reserved */ + 0, /* 64: Reserved */ + 0, /* 65: Reserved */ + 0, /* 66: Reserved */ + 0, /* 67: Reserved */ + 0, /* 68: Reserved */ + GPIO0_Combined_Handler, /* 69: GPIO 0 Combined Handler */ + GPIO1_Combined_Handler, /* 70: GPIO 1 Combined Handler */ + GPIO2_Combined_Handler, /* 71: GPIO 2 Combined Handler */ + GPIO3_Combined_Handler, /* 72: GPIO 3 Combined Handler */ + GPIO0_0_Handler, /* 73: GPIO0 Pin 0 Handler */ + GPIO0_1_Handler, /* 74: GPIO0 Pin 1 Handler */ + GPIO0_2_Handler, /* 75: GPIO0 Pin 2 Handler */ + GPIO0_3_Handler, /* 76: GPIO0 Pin 3 Handler */ + GPIO0_4_Handler, /* 77: GPIO0 Pin 4 Handler */ + GPIO0_5_Handler, /* 78: GPIO0 Pin 5 Handler */ + GPIO0_6_Handler, /* 79: GPIO0 Pin 6 Handler */ + GPIO0_7_Handler, /* 80: GPIO0 Pin 7 Handler */ + GPIO0_8_Handler, /* 81: GPIO0 Pin 8 Handler */ + GPIO0_9_Handler, /* 82: GPIO0 Pin 9 Handler */ + GPIO0_10_Handler, /* 83: GPIO0 Pin 10 Handler */ + GPIO0_11_Handler, /* 84: GPIO0 Pin 11 Handler */ + GPIO0_12_Handler, /* 85: GPIO0 Pin 12 Handler */ + GPIO0_13_Handler, /* 86: GPIO0 Pin 13 Handler */ + GPIO0_14_Handler, /* 87: GPIO0 Pin 14 Handler */ + GPIO0_15_Handler, /* 88: GPIO0 Pin 15 Handler */ + GPIO1_0_Handler, /* 89: GPIO1 Pin 0 Handler */ + GPIO1_1_Handler, /* 90: GPIO1 Pin 1 Handler */ + GPIO1_2_Handler, /* 91: GPIO1 Pin 2 Handler */ + GPIO1_3_Handler, /* 92: GPIO1 Pin 3 Handler */ + GPIO1_4_Handler, /* 93: GPIO1 Pin 4 Handler */ + GPIO1_5_Handler, /* 94: GPIO1 Pin 5 Handler */ + GPIO1_6_Handler, /* 95: GPIO1 Pin 6 Handler */ + GPIO1_7_Handler, /* 96: GPIO1 Pin 7 Handler */ + GPIO1_8_Handler, /* 97: GPIO1 Pin 8 Handler */ + GPIO1_9_Handler, /* 98: GPIO1 Pin 9 Handler */ + GPIO1_10_Handler, /* 99: GPIO1 Pin 10 Handler */ + GPIO1_11_Handler, /* 100: GPIO1 Pin 11 Handler */ + GPIO1_12_Handler, /* 101: GPIO1 Pin 12 Handler */ + GPIO1_13_Handler, /* 102: GPIO1 Pin 13 Handler */ + GPIO1_14_Handler, /* 103: GPIO1 Pin 14 Handler */ + GPIO1_15_Handler, /* 104: GPIO1 Pin 15 Handler */ + GPIO2_0_Handler, /* 105: GPIO2 Pin 0 Handler */ + GPIO2_1_Handler, /* 106: GPIO2 Pin 1 Handler */ + GPIO2_2_Handler, /* 107: GPIO2 Pin 2 Handler */ + GPIO2_3_Handler, /* 108: GPIO2 Pin 3 Handler */ + GPIO2_4_Handler, /* 109: GPIO2 Pin 4 Handler */ + GPIO2_5_Handler, /* 110: GPIO2 Pin 5 Handler */ + GPIO2_6_Handler, /* 111: GPIO2 Pin 6 Handler */ + GPIO2_7_Handler, /* 112: GPIO2 Pin 7 Handler */ + GPIO2_8_Handler, /* 113: GPIO2 Pin 8 Handler */ + GPIO2_9_Handler, /* 114: GPIO2 Pin 9 Handler */ + GPIO2_10_Handler, /* 115: GPIO2 Pin 10 Handler */ + GPIO2_11_Handler, /* 116: GPIO2 Pin 11 Handler */ + GPIO2_12_Handler, /* 117: GPIO2 Pin 12 Handler */ + GPIO2_13_Handler, /* 118: GPIO2 Pin 13 Handler */ + GPIO2_14_Handler, /* 119: GPIO2 Pin 14 Handler */ + GPIO2_15_Handler, /* 120: GPIO2 Pin 15 Handler */ + GPIO3_0_Handler, /* 121: GPIO3 Pin 0 Handler */ + GPIO3_1_Handler, /* 122: GPIO3 Pin 1 Handler */ + GPIO3_2_Handler, /* 123: GPIO3 Pin 2 Handler */ + GPIO3_3_Handler, /* 124: GPIO3 Pin 3 Handler */ + UARTRX5_Handler, /* 125: UART 5 RX Interrupt */ + UARTTX5_Handler, /* 126: UART 5 TX Interrupt */ + UART5_Handler, /* 127: UART 5 combined Interrupt */ + 0, /* 128: Reserved */ + 0, /* 129: Reserved */ + 0, /* 130: Reserved */ +}; + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +/*---------------------------------------------------------------------------- + Reset Handler called on controller reset + *----------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + __set_MSPLIM((uint32_t)(&__STACK_LIMIT)); + + SystemInit(); /* CMSIS System Initialization */ + __PROGRAM_START(); /* Enter PreMain (C library entry point) */ +} diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c new file mode 100644 index 000000000..1d8c3b674 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2009-2022 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.c + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#include "SSE300MPS3.h" + +/*---------------------------------------------------------------------------- + Define clocks + *----------------------------------------------------------------------------*/ + #define XTAL (32000000UL) + #define SYSTEM_CLOCK (XTAL) + #define PERIPHERAL_CLOCK (25000000UL) + +/*---------------------------------------------------------------------------- + Externals + *----------------------------------------------------------------------------*/ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + extern uint32_t __VECTOR_TABLE; +#endif + +/*---------------------------------------------------------------------------- + System Core Clock Variable + *----------------------------------------------------------------------------*/ +uint32_t SystemCoreClock = SYSTEM_CLOCK; +uint32_t PeripheralClock = PERIPHERAL_CLOCK; + +/*---------------------------------------------------------------------------- + System Core Clock update function + *----------------------------------------------------------------------------*/ +void SystemCoreClockUpdate (void) +{ + SystemCoreClock = SYSTEM_CLOCK; + PeripheralClock = PERIPHERAL_CLOCK; +} + +/*---------------------------------------------------------------------------- + System initialization function + *----------------------------------------------------------------------------*/ +void SystemInit (void) +{ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + SCB->VTOR = (uint32_t)(&__VECTOR_TABLE); +#endif + +#if (defined (__FPU_USED) && (__FPU_USED == 1U)) || \ + (defined (__ARM_FEATURE_MVE) && (__ARM_FEATURE_MVE >= 1U)) + SCB->CPACR |= ((3U << 10U*2U) | /* enable CP10 Full Access */ + (3U << 11U*2U) ); /* enable CP11 Full Access */ + + /* Set CPDLPSTATE.CLPSTATE to 0, so PDCORE will not enter low-power state. Set + * CPDLPSTATE.ELPSTATE to 0, to stop the processor from trying to switch the EPU + * into retention state + */ + PWRMODCTL->CPDLPSTATE &= 0xFFFFFF00UL; +#endif + +#ifdef UNALIGNED_SUPPORT_DISABLE + SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk; +#endif + + /* Enable Loop and branch info cache */ + SCB->CCR |= SCB_CCR_LOB_Msk; + __DSB(); + __ISB(); + +} diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h new file mode 100644 index 000000000..feba5e9aa --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/Device/SSE-300-MPS3/system_SSE300MPS3.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2009-2020 Arm Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * This file is derivative of CMSIS V5.6.0 system_ARMv81MML.h + * Git SHA: b5f0603d6a584d1724d952fd8b0737458b90d62b + */ + +#ifndef __SYSTEM_CORE_INIT_H__ +#define __SYSTEM_CORE_INIT_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern uint32_t PeripheralClock; /*!< Peripheral Clock Frequency */ + +/** + * \brief Initializes the system + */ +extern void SystemInit(void); + +/** + * \brief Restores system core clock + */ +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __SYSTEM_CORE_INIT_H__ */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h new file mode 100644 index 000000000..3b0b521d1 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/RTE/_FVP_Simulation_Model/RTE_Components.h @@ -0,0 +1,21 @@ + +/* + * Auto generated Run-Time-Environment Configuration File + * *** Do not modify ! *** + * + * Project: 'demo_threadx_non-secure_zone' + * Target: 'FVP Simulation Model' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "SSE300MPS3.h" + + + +#endif /* RTE_COMPONENTS_H */ diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt new file mode 100644 index 000000000..7ec4b36b6 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvopt @@ -0,0 +1,305 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + ThreadX_Demo + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 1 + 0 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 255 + + 1 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + -1 + + + + + + + + + + + + + + + 0 + ARMRTXEVENTFLAGS + -L70 -Z18 -C0 -M0 -T1 + + + 0 + DLGDARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0) + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + 0 + DLGTARM + (1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(110=-1,-1,-1,-1,0)(100=-1,-1,-1,-1,0)(101=-1,-1,-1,-1,0)(102=-1,-1,-1,-1,0)(103=-1,-1,-1,-1,0)(104=-1,-1,-1,-1,0)(105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0)(161=-1,-1,-1,-1,0)(162=-1,-1,-1,-1,0)(163=-1,-1,-1,-1,0)(164=-1,-1,-1,-1,0)(150=-1,-1,-1,-1,0)(151=-1,-1,-1,-1,0)(152=-1,-1,-1,-1,0)(1011=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)(1013=-1,-1,-1,-1,0)(171=-1,-1,-1,-1,0)(172=-1,-1,-1,-1,0)(173=-1,-1,-1,-1,0)(1014=-1,-1,-1,-1,0)(1016=-1,-1,-1,-1,0)(136=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + -T5F + + + 0 + UL2CM3 + -UV0289BJE -O14 -S0 -C0 -N00("ARM CoreSight JTAG-DP") -D00(3BA00477) -L00(4) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC800 -FN1 -FF0LM3S_16 -FS00 -FL04000 + + + + + + 0 + 1 + thread_0_counter + + + 1 + 1 + thread_1_counter + + + 2 + 1 + thread_2_counter + + + 3 + 1 + thread_3_counter + + + 4 + 1 + thread_4_counter + + + 5 + 1 + thread_5_counter + + + 6 + 1 + _tx_thread_current_ptr + + + + 0 + + + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + + + + Source Group + 1 + 0 + 0 + 0 + + 1 + 1 + 2 + 0 + 0 + 0 + .\tx_initialize_low_level.s + tx_initialize_low_level.s + 0 + 0 + + + 1 + 2 + 1 + 1 + 0 + 0 + .\demo_threadx.c + demo_threadx.c + 0 + 0 + + 44 + 0 + 1 + + -1 + -1 + + + -1 + -1 + + + 56 + 12 + 1633 + 671 + + + + + + + Library_Group + 1 + 0 + 0 + 0 + + 2 + 3 + 4 + 0 + 0 + 0 + .\ThreadX_Library.lib + ThreadX_Library.lib + 0 + 0 + + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj new file mode 100644 index 000000000..5f5dcbdb2 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/ThreadX_Demo.uvproj @@ -0,0 +1,556 @@ + + + + 1.1 + +
### uVision Project, (C) Keil Software
+ + + + ThreadX_Demo + 0x4 + ARM-ADS + 5060750::V5.06 update 6 (build 750)::ARMCC + 0 + + + Cortex-M4 FPU + ARM + CLOCK(12000000) CPUTYPE("Cortex-M4") ESEL ELITTLE FPU2 + + + + 5237 + + + + + + + + + + + + 0 + 0 + + + + Luminary\ + Luminary\ + + 0 + 0 + 0 + 0 + 1 + + .\ + threadx_demo + 1 + 0 + 0 + 1 + 1 + .\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + SARMCM3.DLL + + DCM.DLL + -pCM4F + SARMCM3.DLL + + TCM.DLL + -pCM4F + + + + 1 + 0 + 0 + 0 + 16 + + + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + + + 0 + 1 + 0 + 1 + 1 + 1 + 0 + 1 + 0 + 1 + + 0 + -1 + + + + + + + + + + + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 4096 + + 0 + BIN\UL2CM3.DLL + + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M4" + + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x10000 + + + 1 + 0x0 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + + + + --first __tx_vectors --entry=__main + + + + + + + + Source Group + + + 0 + 1 + 1 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + + + 0 + + + + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + tx_initialize_low_level.s + 2 + .\tx_initialize_low_level.s + + + 2 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 2 + 2 + 1 + 2 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + + + + demo_threadx.c + 1 + .\demo_threadx.c + + + + + Library_Group + + + ThreadX_Library.lib + 4 + .\ThreadX_Library.lib + + + + + + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx.c b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx.c new file mode 100644 index 000000000..7257ac6d4 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx.c @@ -0,0 +1,401 @@ +/* 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. Please refer to Chapter 6 of the ThreadX User Guide for a complete + description of this demonstration. */ + +#include "tx_api.h" +#include "..\demo_secure_zone\interface.h" /* Interface to sample secure functions. */ + +#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... */ + +static TX_THREAD thread_0; +static TX_THREAD thread_1; +static TX_THREAD thread_2; +static TX_THREAD thread_3; +static TX_THREAD thread_4; +static TX_THREAD thread_5; +static TX_THREAD thread_6; +static TX_THREAD thread_7; +static TX_QUEUE queue_0; +static TX_SEMAPHORE semaphore_0; +static TX_MUTEX mutex_0; +static TX_EVENT_FLAGS_GROUP event_flags_0; +static TX_BYTE_POOL byte_pool_0; +static TX_BLOCK_POOL block_pool_0; + +/* Define byte pool memory. */ + +static UCHAR byte_pool_memory[DEMO_BYTE_POOL_SIZE]; + + +/* Define event buffer. */ + +#ifdef TX_ENABLE_EVENT_TRACE +UCHAR trace_buffer[0x10000]; +#endif + + +/* Define the counters used in the demo application... */ + +static ULONG thread_0_counter; +static ULONG thread_1_counter; +static ULONG thread_1_messages_sent; +static ULONG thread_2_counter; +static ULONG thread_2_messages_received; +static ULONG thread_3_counter; +static ULONG thread_4_counter; +static ULONG thread_5_counter; +static ULONG thread_6_counter; +static 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() +{ + + /* Please refer to Chapter 6 of the ThreadX User Guide for a complete + description of this demonstration. */ + + + /* Enter the ThreadX kernel. */ + tx_kernel_enter(); +} + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +CHAR *pointer; + + (VOID)first_unused_memory; /* unused parameter. */ + +#ifdef TX_ENABLE_EVENT_TRACE + tx_trace_enable(trace_buffer, sizeof(trace_buffer), 32); +#endif + + /* Create a byte memory pool from which to allocate the thread stacks. */ + tx_byte_pool_create(&byte_pool_0, "byte pool 0", byte_pool_memory, 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); + + tx_thread_secure_stack_allocate(&thread_0,256); + tx_thread_secure_stack_allocate(&thread_1,256); + tx_thread_secure_stack_allocate(&thread_2,256); + tx_thread_secure_stack_allocate(&thread_3,256); + tx_thread_secure_stack_allocate(&thread_4,256); + tx_thread_secure_stack_allocate(&thread_5,256); + tx_thread_secure_stack_allocate(&thread_6,256); + tx_thread_secure_stack_allocate(&thread_7,256); +} + + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ +UINT status; + + (VOID)thread_input; /* unused parameter. */ + + /* This thread simply sits in while-forever-sleep loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Sleep for 10 ticks. */ + tx_thread_sleep(10); + + /* Set event flag 0 to wakeup thread 5. */ + status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + (VOID)thread_input; /* unused parameter. */ + + /* 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; + + (VOID)thread_input; /* unused parameter. */ + + /* 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; + + (VOID)thread_input; /* unused parameter. */ + + /* 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/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx new file mode 100644 index 000000000..dc8990d28 --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvoptx @@ -0,0 +1,342 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj + *.lib + *.txt; *.h; *.inc; *.md + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + FVP Simulation Model + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + .\Listings\ + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 7 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 15 + + + + + + + + + + ..\Debug.ini + BIN\DbgFMv8M.DLL + + + + 0 + UL2V8M + UL2V8M(-S0 -C0 -P0 -FC1000 -FD01000000 + + + 0 + DbgFMv8M + -I -S -L"cpu0" -O4102 -C0 -MC"$K\ARM\VHT\VHT_MPS3_Corstone_SSE-300.exe" -MF"..\CS300_config.txt" -PF -MA + + + 0 + PWSTATINFO + 200,50,700 + + + 0 + DLGTARM + (6010=-1,-1,-1,-1,0)(6018=-1,-1,-1,-1,0)(6019=-1,-1,-1,-1,0)(6008=-1,-1,-1,-1,0)(6009=-1,-1,-1,-1,0)(6014=-1,-1,-1,-1,0)(6015=-1,-1,-1,-1,0)(6003=-1,-1,-1,-1,0)(6000=-1,-1,-1,-1,0)(6020=-1,-1,-1,-1,0) + + + 0 + ARMDBGFLAGS + + + + 0 + DLGUARM + (105=-1,-1,-1,-1,0)(106=-1,-1,-1,-1,0)(107=-1,-1,-1,-1,0) + + + + + + 0 + 1 + thread_0_counter + + + 1 + 1 + thread_1_counter + + + 2 + 1 + thread_2_counter + + + 3 + 1 + thread_3_counter + + + 4 + 1 + thread_4_counter + + + 5 + 1 + thread_5_counter + + + 6 + 1 + thread_6_counter + + + 7 + 1 + thread_7_counter + + + + + 1 + 2 + 0x00040400 + 0 + + + + 0 + + + 0 + 1 + 1 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + + + + + 1 + 1 + 0 + 2 + 10000000 + + + + + + Non-secure Code + 1 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + .\demo_threadx.c + demo_threadx.c + 0 + 0 + + + 1 + 2 + 4 + 0 + 0 + 0 + ..\ThreadX_Library.lib + ThreadX_Library.lib + 0 + 0 + + + + + CMSE Library + 1 + 0 + 0 + 0 + + 2 + 3 + 5 + 0 + 0 + 0 + ..\demo_secure_zone\interface.h + interface.h + 0 + 0 + + + 2 + 4 + 3 + 0 + 0 + 0 + ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o + demo_secure_zone_CMSE_Lib.o + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + + + ::Device + 0 + 0 + 0 + 1 + + + + ::Native Driver + 0 + 0 + 0 + 1 + + +
diff --git a/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx new file mode 100644 index 000000000..fc585a9fc --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/demo_threadx_non-secure_zone/demo_threadx_non-secure_zone.uvprojx @@ -0,0 +1,569 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + FVP Simulation Model + 0x4 + ARM-ADS + 6180000::V6.18::ARMCLANG + 1 + + + SSE-300-MPS3 + ARM + ARM.V2M_MPS3_SSE_300_BSP.1.3.0 + http://www.keil.com/pack/ + IRAM(0x00000000,0x00080000) IRAM2(0x01000000,0x00200000) XRAM(0x20000000,0x00020000) XRAM2(0x20020000,0x00020000) XRAM3(0x20040000,0x00020000) CPUTYPE("Cortex-M55") FPU3(DFPU) DSP TZ MVE(FP) CLOCK(12000000) ESEL ELITTLE + + + UL2V8M(-S0 -C0 -P0 -FD01000000 -FC1000) + 0 + $$Device:SSE-300-MPS3$Device\Include\SSE300MPS3.h + + + + + + + + + + $$Device:SSE-300-MPS3$SVD\SSE300.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + .\Objects\ + demo_threadx_non-secure_zone + 1 + 0 + 0 + 1 + 1 + .\Listings\ + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 1 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 1 + + + + + + + SARMV8M.DLL + -MPU -MVE + TCM.DLL + -pCM55 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 0 + 4102 + + 1 + BIN\UL2V8M.DLL + "" () + + + + + 0 + + + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 1 + 0 + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + "Cortex-M55" + + 0 + 0 + 0 + 0 + 1 + 1 + 0 + 3 + 2 + 0 + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 4 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + 1 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x80000 + + + 1 + 0x0 + 0x200000 + + + 1 + 0x20000000 + 0x20000 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x20000 + + + 0 + 0x20020000 + 0x20000 + + + 0 + 0x20040000 + 0x20000 + + + 0 + 0x0 + 0x80000 + + + 0 + 0x1000000 + 0x200000 + + + + + + 1 + 2 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 3 + 0 + 0 + 0 + 0 + 0 + 3 + 1 + 1 + 1 + 0 + 0 + 0 + + + + + ..\..\..\..\..\common\inc, ..\..\inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + + + + + + + + 0 + 0 + 0 + 0 + 1 + 0 + 0x00000000 + 0x20000000 + + ..\CS300_ac6.sct + + + + + + + + + + + Non-secure Code + + + demo_threadx.c + 1 + .\demo_threadx.c + + + ThreadX_Library.lib + 4 + ..\ThreadX_Library.lib + + + + + CMSE Library + + + interface.h + 5 + ..\demo_secure_zone\interface.h + + + demo_secure_zone_CMSE_Lib.o + 3 + ..\demo_secure_zone\Objects\demo_secure_zone_CMSE_Lib.o + + + + + ::CMSIS + + + ::Device + + + ::Native Driver + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\ARMCM33_ac6.sct + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\startup_ARMCM33.c + + + + + + RTE\Device\ARMCM33_DSP_FP_TZ\system_ARMCM33.c + + + + + + RTE\Device\SSE-300-MPS3\RTE_Device.h + + + + + + + + RTE\Device\SSE-300-MPS3\cmsis_driver_config.h + + + + + + + + RTE\Device\SSE-300-MPS3\device_cfg.h + + + + + + + + RTE\Device\SSE-300-MPS3\fvp_sse300_mps3_s.sct + + + + + + + + RTE\Device\SSE-300-MPS3\platform_base_address.h + + + + + + + + RTE\Device\SSE-300-MPS3\region_defs.h + + + + + + + + RTE\Device\SSE-300-MPS3\region_limits.h + + + + + + + + RTE\Device\SSE-300-MPS3\startup_fvp_sse300_mps3.c + + + + + + + + RTE\Device\SSE-300-MPS3\system_SSE300MPS3.c + + + + + + + + RTE\Device\SSE-300-MPS3\system_SSE300MPS3.h + + + + + + + + + +
diff --git a/ports/cortex_m55/ac6/example_build/tx_initialize_low_level.S b/ports/cortex_m55/ac6/example_build/tx_initialize_low_level.S new file mode 100644 index 000000000..b1c85cb3b --- /dev/null +++ b/ports/cortex_m55/ac6/example_build/tx_initialize_low_level.S @@ -0,0 +1,278 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + +SYSTEM_CLOCK = 25000000 +SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1) + +/* Setup the stack and heap areas. */ + +STACK_SIZE = 0x00000400 +HEAP_SIZE = 0x00000000 + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_initialize_low_level Cortex-M33/AC6 */ +/* 6.1 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 09-30-2020 Scott Larson Initial Version 6.1 */ +/* */ +/**************************************************************************/ +// VOID _tx_initialize_low_level(VOID) +// { + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global _tx_initialize_low_level + .thumb_func +.type _tx_initialize_low_level, function +_tx_initialize_low_level: + + /* Disable interrupts during ThreadX initialization. */ + CPSID i + + /* Set base of available memory to end of non-initialised RAM area. */ + LDR r0, =_tx_initialize_unused_memory // Build address of unused memory pointer + LDR r1, =Image$$ARM_LIB_STACK$$ZI$$Limit // Build first free address + ADD r1, r1, #4 // + STR r1, [r0] // Setup first unused memory pointer + + /* Setup Vector Table Offset Register. */ + MOV r0, #0xE000E000 // Build address of NVIC registers + LDR r1, =__Vectors // Pickup address of vector table + STR r1, [r0, #0xD08] // Set vector table address + + /* Enable the cycle count register. */ + LDR r0, =0xE0001000 // Build address of DWT register + LDR r1, [r0] // Pickup the current value + ORR r1, r1, #1 // Set the CYCCNTENA bit + STR r1, [r0] // Enable the cycle count register + + /* Set system stack pointer from vector value. */ + LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer + LDR r1, =__Vectors // Pickup address of vector table + LDR r1, [r1] // Pickup reset stack pointer + STR r1, [r0] // Save system stack pointer + + /* Configure SysTick. */ + MOV r0, #0xE000E000 // Build address of NVIC registers + LDR r1, =SYSTICK_CYCLES + STR r1, [r0, #0x14] // Setup SysTick Reload Value + MOV r1, #0x7 // Build SysTick Control Enable Value + STR r1, [r0, #0x10] // Setup SysTick Control + + /* Configure handler priorities. */ + LDR r1, =0x00000000 // Rsrv, UsgF, BusF, MemM + STR r1, [r0, #0xD18] // Setup System Handlers 4-7 Priority Registers + + LDR r1, =0xFF000000 // SVCl, Rsrv, Rsrv, Rsrv + STR r1, [r0, #0xD1C] // Setup System Handlers 8-11 Priority Registers + // Note: SVC must be lowest priority, which is 0xFF + + LDR r1, =0x40FF0000 // SysT, PnSV, Rsrv, DbgM + STR r1, [r0, #0xD20] // Setup System Handlers 12-15 Priority Registers + // Note: PnSV must be lowest priority, which is 0xFF + + /* Return to caller. */ + BX lr +// } + + +/* Define shells for each of the unused vectors. */ + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global __tx_BadHandler + .thumb_func +.type __tx_BadHandler, function +__tx_BadHandler: + B __tx_BadHandler + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global __tx_IntHandler + .thumb_func +.type __tx_IntHandler, function +__tx_IntHandler: +// VOID InterruptHandler (VOID) +// { + PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + BL _tx_execution_isr_enter // Call the ISR enter function +#endif + /* Do interrupt handler work here */ + /* .... */ +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + BL _tx_execution_isr_exit // Call the ISR exit function +#endif + POP {r0,lr} + BX LR +// } + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global SysTick_Handler + .thumb_func +.type SysTick_Handler, function +SysTick_Handler: +// VOID TimerInterruptHandler (VOID) +// { + PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + BL _tx_execution_isr_enter // Call the ISR enter function +#endif + BL _tx_timer_interrupt +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + BL _tx_execution_isr_exit // Call the ISR exit function +#endif + POP {r0,lr} + BX LR +// } + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global HardFault_Handler + .thumb_func +.type HardFault_Handler, function +HardFault_Handler: + B HardFault_Handler + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global UsageFault_Handler + .thumb_func +.type UsageFault_Handler, function +UsageFault_Handler: + CPSID i // Disable interrupts + // Check for stack limit fault + LDR r0, =0xE000ED28 // CFSR address + LDR r1,[r0] // Pick up CFSR + TST r1, #0x00100000 // Check for Stack Overflow +_unhandled_usage_loop: + BEQ _unhandled_usage_loop // If not stack overflow then loop + + // Handle stack overflow + STR r1, [r0] // Clear CFSR flag(s) + +#ifdef __ARM_PCS_VFP + LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address + LDR r1, [r0] // Load FPCCR + BIC r1, r1, #1 // Clear the lazy preservation active bit + STR r1, [r0] // Store the value +#endif + + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + LDR r0,[r0] // Pick up current thread pointer + PUSH {r0,lr} // Save LR (and r0 to maintain stack alignment) + BL _tx_thread_stack_error_handler // Call ThreadX/user handler + POP {r0,lr} // Restore LR and dummy reg + +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) + // Call the thread exit function to indicate the thread is no longer executing. + PUSH {r0, lr} // Save LR (and r0 just for alignment) + BL _tx_execution_thread_exit // Call the thread exit function + POP {r0, lr} // Recover LR +#endif + + MOV r1, #0 // Build NULL value + LDR r0, =_tx_thread_current_ptr // Pickup address of current thread pointer + STR r1, [r0] // Clear current thread pointer + + // Return from UsageFault_Handler exception + LDR r0, =0xE000ED04 // Load ICSR + LDR r1, =0x10000000 // Set PENDSVSET bit + STR r1, [r0] // Store ICSR + DSB // Wait for memory access to complete + CPSIE i // Enable interrupts + BX lr // Return from exception + + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global __tx_NMIHandler + .thumb_func +.type __tx_NMIHandler, function +__tx_NMIHandler: + B __tx_NMIHandler + + + .section .text + .balign 4 + .syntax unified + .eabi_attribute Tag_ABI_align_preserved, 1 + .global __tx_DBGHandler + .thumb_func +.type __tx_DBGHandler, function +__tx_DBGHandler: + B __tx_DBGHandler + + .end diff --git a/ports/cortex_m55/iar/src/tx_misra.s b/ports/cortex_m55/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m55/iar/src/tx_misra.s +++ b/ports/cortex_m55/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m7/iar/src/tx_misra.s b/ports/cortex_m7/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m7/iar/src/tx_misra.s +++ b/ports/cortex_m7/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/cortex_m85/iar/src/tx_misra.s b/ports/cortex_m85/iar/src/tx_misra.s index c81c3e5cc..ab3fef693 100644 --- a/ports/cortex_m85/iar/src/tx_misra.s +++ b/ports/cortex_m85/iar/src/tx_misra.s @@ -111,9 +111,9 @@ PUBLIC _tx_misra_semaphore_put_notify_not_used PUBLIC _tx_misra_thread_entry_exit_notify_not_used PUBLIC _tx_misra_thread_not_used - - PUBLIC _tx_version_id +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA @@ -130,6 +130,7 @@ _tx_version_id: DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ diff --git a/ports/rxv1/ccrx/readme_threadx.txt b/ports/rxv1/ccrx/readme_threadx.txt index 40d980267..a104a9f21 100644 --- a/ports/rxv1/ccrx/readme_threadx.txt +++ b/ports/rxv1/ccrx/readme_threadx.txt @@ -28,7 +28,8 @@ 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. +level 5 with the symbol CMT_RX_CFG_IPR in r_cmt_rx_config.h of Renesas CMT timer module +(r_cmt_rx). 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 @@ -40,12 +41,12 @@ _tx_initialize_unused_memory 4. Context Switch, Register Usage and Stack Frames -The RXv1 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 RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -96,17 +97,17 @@ defined before tx_api.h is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to -define interupt service routines. +define interrupt service routines. 8. Execution Profiling diff --git a/ports/rxv1/gnu/readme_threadx.txt b/ports/rxv1/gnu/readme_threadx.txt index 849bfc766..d1b74f6c4 100644 --- a/ports/rxv1/gnu/readme_threadx.txt +++ b/ports/rxv1/gnu/readme_threadx.txt @@ -27,7 +27,8 @@ initialization code. The ThreadX demonstration for the RXv1 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 +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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. @@ -41,12 +42,12 @@ sections in your linker control file. 4. Context Switch, Register Usage and Stack Frames -The RXv1 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 RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -96,15 +97,15 @@ is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 effects but doing so may slightly reduce +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to define interrupt service routines. diff --git a/ports/rxv1/iar/readme_threadx.txt b/ports/rxv1/iar/readme_threadx.txt index cf3183933..a9d8137ac 100644 --- a/ports/rxv1/iar/readme_threadx.txt +++ b/ports/rxv1/iar/readme_threadx.txt @@ -26,8 +26,9 @@ initialization code. The ThreadX demonstration for the RXv1 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. +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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 @@ -38,12 +39,12 @@ sections in your linker control file. 4. Context Switch, Register Usage and Stack Frames -The RXv1 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 RXv1 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -93,15 +94,15 @@ is included. Timer procession 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 effects but doing so may slightly reduce +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to define interrupt service routines. diff --git a/ports/rxv2/ccrx/readme_threadx.txt b/ports/rxv2/ccrx/readme_threadx.txt index 7ab448c9c..2b6bd50cb 100644 --- a/ports/rxv2/ccrx/readme_threadx.txt +++ b/ports/rxv2/ccrx/readme_threadx.txt @@ -28,7 +28,8 @@ 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. +level 5 with the symbol CMT_RX_CFG_IPR in r_cmt_rx_config.h of Renesas CMT timer module +(r_cmt_rx). 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 @@ -40,12 +41,12 @@ _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 RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -99,17 +100,17 @@ defined before tx_api.h is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to -define interupt service routines. +define interrupt service routines. 8. Execution Profiling diff --git a/ports/rxv2/gnu/readme_threadx.txt b/ports/rxv2/gnu/readme_threadx.txt index ffbb4035b..c1ac99124 100644 --- a/ports/rxv2/gnu/readme_threadx.txt +++ b/ports/rxv2/gnu/readme_threadx.txt @@ -27,7 +27,8 @@ 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 +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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. @@ -41,12 +42,12 @@ 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 RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -99,17 +100,17 @@ is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to -define interupt service routines. +define interrupt service routines. 8. Execution Profiling diff --git a/ports/rxv2/iar/readme_threadx.txt b/ports/rxv2/iar/readme_threadx.txt index a00744397..5f09a2b33 100644 --- a/ports/rxv2/iar/readme_threadx.txt +++ b/ports/rxv2/iar/readme_threadx.txt @@ -26,8 +26,9 @@ 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. +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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 @@ -38,12 +39,12 @@ 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 RXv2 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -96,17 +97,17 @@ is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) 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 +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to -define interupt service routines. +define interrupt service routines. 8. Execution Profiling diff --git a/ports/rxv3/ccrx/readme_threadx.txt b/ports/rxv3/ccrx/readme_threadx.txt index 3524663f4..cbc8149df 100644 --- a/ports/rxv3/ccrx/readme_threadx.txt +++ b/ports/rxv3/ccrx/readme_threadx.txt @@ -28,7 +28,8 @@ 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. +level 5 with the symbol CMT_RX_CFG_IPR in r_cmt_rx_config.h of Renesas CMT timer module +(r_cmt_rx). 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 @@ -40,12 +41,12 @@ _tx_initialize_unused_memory 4. Context Switch, Register Usage and Stack Frames -The RXv3 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 RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -155,15 +156,15 @@ defined before tx_api.h is included. Timer processing 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) is used as the timer source. 8. 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 effect but doing so may slightly reduce +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to define interrupt service routines. diff --git a/ports/rxv3/gnu/readme_threadx.txt b/ports/rxv3/gnu/readme_threadx.txt index fbe3c43ef..3d68313ca 100644 --- a/ports/rxv3/gnu/readme_threadx.txt +++ b/ports/rxv3/gnu/readme_threadx.txt @@ -27,7 +27,8 @@ initialization code. The ThreadX demonstration for the RXv3 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 +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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. @@ -41,12 +42,12 @@ sections in your linker control file. 4. Context Switch, Register Usage and Stack Frames -The RXv3 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 RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -153,15 +154,15 @@ is included. Timer processing 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) is used as the timer source. 8. 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 effects but doing so may slightly reduce +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effects but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to define interrupt service routines. diff --git a/ports/rxv3/iar/readme_threadx.txt b/ports/rxv3/iar/readme_threadx.txt index 7c0865c48..2100d92de 100644 --- a/ports/rxv3/iar/readme_threadx.txt +++ b/ports/rxv3/iar/readme_threadx.txt @@ -26,8 +26,9 @@ initialization code. The ThreadX demonstration for the RXv3 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. +interrupt priority level is set to level 5 with the symbol CMT_RX_CFG_IPR in +r_cmt_rx_config.h of Renesas CMT timer module(r_cmt_rx). 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 @@ -38,12 +39,12 @@ sections in your linker control file. 4. Context Switch, Register Usage and Stack Frames -The RXv3 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 RXv3 port for ThreadX uses the first software interrupt, SWINT, i.e., interrupt #27, +to perform context switch with the interrupt priority level 1. 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 @@ -153,17 +154,17 @@ is included. 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. +a Renesas Fit CMT periodic timer module (r_cmt_rx) is used as the timer source. 8. 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 +priority 1 as this is the priority of the context switch interrupt. However using interrupt +priority 1 won't cause any negative side effectd but doing so may slightly reduce performance. Please refer to the toolchain documentation for additional details on how to -define interupt service routines. +define interrupt service routines. 9. Execution Profiling diff --git a/ports/xtensa/xcc/inc/tx_port.h b/ports/xtensa/xcc/inc/tx_port.h index eb74a88c1..82ee5f974 100644 --- a/ports/xtensa/xcc/inc/tx_port.h +++ b/ports/xtensa/xcc/inc/tx_port.h @@ -11,36 +11,39 @@ /**************************************************************************/ /**************************************************************************/ -/** */ +/** */ /** 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. */ +/**************************************************************************/ +/* */ +/* 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 */ /* */ -/* RELEASE HISTORY */ -/* */ -/* DATE NAME DESCRIPTION */ -/* */ -/* 11-09-2020 Cadence Design Systems Initial Version 6.1.2 */ -/* 04-02-2021 Bhupendra Naphade Modified comment(s),updated */ -/* macro definition, */ -/* resulting in version 6.1.6 */ -/* */ -/**************************************************************************/ +/* DATE NAME DESCRIPTION */ +/* */ +/* 11-09-2020 Cadence Design Systems Initial Version 6.1.2 */ +/* 04-02-2021 Bhupendra Naphade Modified comment(s), updated */ +/* macro definition, */ +/* resulting in version 6.1.6 */ +/* 10-31-2022 Scott Larson Modified comment(s), removed */ +/* EPK extension, */ +/* resulting in version 6.2.0 */ +/* */ +/**************************************************************************/ #ifndef TX_PORT_H #define TX_PORT_H @@ -62,7 +65,7 @@ /* Some generic C sources call memset() and need this (else compiler warns). Until the generic sources take care of this, do it here. */ - + #include @@ -74,7 +77,7 @@ 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 + beginning of TX_THREAD where assembly code can easily get to it at a fixed offset. */ @@ -108,7 +111,7 @@ extern void _tx_clib_thread_setup(struct TX_THREAD_STRUCT *thread_ptr); #endif -/* Define ThreadX basic types for this port. */ +/* Define ThreadX basic types for this port. */ #define VOID void typedef char CHAR; @@ -135,11 +138,11 @@ typedef unsigned short USHORT; /* 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 + 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 + 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 @@ -147,8 +150,8 @@ typedef unsigned short USHORT; 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 + 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. */ @@ -186,15 +189,15 @@ typedef unsigned short USHORT; /* 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 + 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(). + 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 @@ -235,12 +238,12 @@ typedef unsigned short USHORT; #ifndef __ASSEMBLER__ -#ifndef TX_TIMER_THREAD_PRIORITY -#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ +#ifndef TX_TIMER_THREAD_PRIORITY +#define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif -/* Define various constants for the ThreadX Xtensa port. */ +/* Define various constants for the ThreadX Xtensa port. */ #if XCHAL_HAVE_XEA3 #define TX_INT_DISABLE 0x8 /* Disable interrupts value */ @@ -252,9 +255,9 @@ typedef unsigned short USHORT; /* - 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 + 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) @@ -313,9 +316,9 @@ typedef unsigned short USHORT; /* 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 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 + the TX_DISABLE_STACK_FILLING define is canceled, thereby forcing the stack fill which is necessary for the stack checking logic. */ @@ -326,7 +329,7 @@ typedef unsigned short USHORT; /* Define the TX_THREAD control block extensions for this port. The main - reason for the multiple macros is so that backward compatibility can + reason for the multiple macros is so that backward compatibility can be maintained with existing ThreadX kernel awareness modules. */ @@ -350,10 +353,7 @@ typedef unsigned short USHORT; #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 TX_THREAD_EXTENSION_3 /* Define the port extensions of the remaining ThreadX objects. */ @@ -366,11 +366,11 @@ typedef unsigned short USHORT; #define TX_TIMER_EXTENSION -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -470,8 +470,8 @@ extern int xt_timer_intnum; /* 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.9 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * Azure RTOS Xtensa Version 6.2.0 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports/xtensa/xcc/src/tx_thread_context_restore.S b/ports/xtensa/xcc/src/tx_thread_context_restore.S index aa6287514..69f3877e6 100644 --- a/ports/xtensa/xcc/src/tx_thread_context_restore.S +++ b/ports/xtensa/xcc/src/tx_thread_context_restore.S @@ -34,8 +34,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** ThreadX Component */ +/** */ +/** ThreadX Component */ /** */ /** Thread */ /** */ @@ -51,19 +51,21 @@ .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 */ +/**************************************************************************/ +/* */ +/* 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 */ +/* 10-31-2022 Scott Larson Updated EPK definitions, */ +/* resulting in version 6.2.0 */ +/* */ +/**************************************************************************/ // VOID _tx_thread_context_restore(VOID) // { @@ -73,16 +75,16 @@ _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 + 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 + #if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the ISR exit function to indicate an ISR is complete. */ #ifdef __XTENSA_CALL0_ABI__ call0 _tx_execution_isr_exit @@ -106,7 +108,7 @@ _tx_thread_context_restore: .Ln_tx_thread_not_nested_restore: /* Determine if a thread was interrupted and no preemption is required. */ - // else if (((_tx_thread_current_ptr) + // else if (((_tx_thread_current_ptr) // && (_tx_thread_current_ptr == _tx_thread_execute_ptr)) // || (_tx_thread_preempt_disable)) // { @@ -124,7 +126,7 @@ _tx_thread_context_restore: // /* the no-preempt case has moved down so we fall-thru to preempt */ bgei a3, 1, .L_tx_thread_no_preempt_restore - + // } // else // { @@ -137,7 +139,7 @@ _tx_thread_context_restore: /* 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(). + 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 @@ -151,7 +153,7 @@ _tx_thread_context_restore: 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_thread_current_ptr -> tx_thread_time_slice // = _tx_timer_time_slice; // _tx_timer_time_slice = 0; */ s32i a4, a2, tx_thread_time_slice @@ -175,7 +177,7 @@ _tx_thread_context_restore: .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. @@ -202,8 +204,8 @@ _tx_thread_context_restore: 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 + 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. */ diff --git a/ports/xtensa/xcc/src/tx_thread_schedule.S b/ports/xtensa/xcc/src/tx_thread_schedule.S index 287c35309..e4b9502ea 100644 --- a/ports/xtensa/xcc/src/tx_thread_schedule.S +++ b/ports/xtensa/xcc/src/tx_thread_schedule.S @@ -34,8 +34,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** ThreadX Component */ +/** */ +/** ThreadX Component */ /** */ /** Thread */ /** */ @@ -49,21 +49,23 @@ .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 */ -/* */ -/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/* 10-31-2022 Scott Larson Updated EPK definitions, */ +/* resulting in version 6.2.0 */ +/* */ +/**************************************************************************/ // VOID _tx_thread_schedule(VOID) // { @@ -96,8 +98,8 @@ _tx_thread_schedule: 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 + 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. */ @@ -108,11 +110,11 @@ _tx_thread_schedule: call0 scheduler_return #endif - /* + /* Wait for a thread to execute (Idle Loop). - First ensure interrupts (except hi-pri) are disabled so result + 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 + While there's no thread ready, enable interrupts and wait in a low power state, then disable interrupts and repeat the test. */ // do @@ -130,7 +132,7 @@ _tx_thread_schedule: // 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. */ @@ -170,7 +172,7 @@ _tx_thread_schedule: // SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; l32i sp, a2, tx_thread_stack_ptr - #ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY + #if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread entry function to indicate the thread is executing. */ #ifdef __XTENSA_CALL0_ABI__ call0 _tx_execution_thread_enter @@ -197,8 +199,8 @@ _tx_thread_schedule: /* 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 + l32i a14, sp, XT_STK_A14 + l32i a15, sp, XT_STK_A15 #endif #if XCHAL_CP_NUM > 0 @@ -207,25 +209,25 @@ _tx_thread_schedule: /* 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 + 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 + 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 + 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 + 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 */ diff --git a/ports/xtensa/xcc/src/tx_thread_system_return.S b/ports/xtensa/xcc/src/tx_thread_system_return.S index e90109c19..e3b5a24e5 100644 --- a/ports/xtensa/xcc/src/tx_thread_system_return.S +++ b/ports/xtensa/xcc/src/tx_thread_system_return.S @@ -34,8 +34,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** ThreadX Component */ +/** */ +/** ThreadX Component */ /** */ /** Thread */ /** */ @@ -48,21 +48,23 @@ .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 */ -/* */ -/**************************************************************************/ +/**************************************************************************/ +/* */ +/* 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 */ +/* 10-31-2022 Scott Larson Updated EPK definitions, */ +/* resulting in version 6.2.0 */ +/* */ +/**************************************************************************/ // VOID _tx_thread_system_return(VOID) // { @@ -91,7 +93,7 @@ _tx_thread_system_return: #endif #endif -#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY +#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) /* Call the thread exit function to indicate the thread is no longer executing. */ #ifdef __XTENSA_CALL0_ABI__ call0 _tx_execution_thread_exit @@ -144,7 +146,7 @@ _tx_thread_system_return: call0 _xt_coproc_savecs /* Clear CPENABLE and give up all co-procs. */ - s16i a5, a4, tx_thread_cp_state + XT_CPENABLE + s16i a5, a4, tx_thread_cp_state + XT_CPENABLE wsr a5, CPENABLE /* disable all co-processors */ #endif @@ -276,7 +278,7 @@ _tx_thread_system_return: 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. */ diff --git a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S index 0e0c8f671..84ba8ae63 100644 --- a/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m0+/ac6/module_manager/src/tx_thread_schedule.S @@ -30,7 +30,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M0+/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -68,6 +68,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -278,11 +280,25 @@ __tx_ts_wait: LDR r1, [r2] // Pickup the next thread to execute pointer CMP r1, #0 BNE __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S index 7e613c25e..78493121e 100644 --- a/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m0+/gnu/module_manager/src/tx_thread_schedule.S @@ -30,7 +30,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M0+/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -68,6 +68,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -278,11 +280,25 @@ __tx_ts_wait: LDR r1, [r2] // Pickup the next thread to execute pointer CMP r1, #0 BNE __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S index af30dffae..1149757a6 100644 --- a/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m0+/iar/module_manager/src/tx_thread_schedule.S @@ -36,7 +36,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M0+/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -75,6 +75,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -263,11 +265,25 @@ __tx_ts_wait: LDR r1, [r2] // Pickup the next thread to execute pointer CMP r1, #0 BNE __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S index 69e8a192a..2610edb52 100644 --- a/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m23/ac6/module_manager/src/tx_thread_schedule.S @@ -30,7 +30,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M23/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -68,6 +68,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -306,11 +308,25 @@ __tx_ts_wait: CPSID i // Disable interrupts LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S index 439a96c05..1a92839ae 100644 --- a/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m23/gnu/module_manager/src/tx_thread_schedule.S @@ -26,7 +26,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M23/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -64,6 +64,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -302,11 +304,25 @@ __tx_ts_wait: CPSID i // Disable interrupts LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s index 00f1189a4..c21fa411c 100644 --- a/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m23/iar/module_manager/src/tx_thread_schedule.s @@ -42,7 +42,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M23/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -80,6 +80,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -303,11 +305,25 @@ __tx_ts_wait: CPSID i // Disable interrupts LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + CPSIE i // Enable interrupts B __tx_ts_wait // Loop to continue waiting diff --git a/ports_module/cortex_m3/ac5/inc/tx_port.h b/ports_module/cortex_m3/ac5/inc/tx_port.h index 0374d55ed..79177b2b8 100644 --- a/ports_module/cortex_m3/ac5/inc/tx_port.h +++ b/ports_module/cortex_m3/ac5/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M3/AC5 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M3 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,14 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifndef TX_MISRA_ENABLE -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -231,37 +308,72 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -270,78 +382,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -366,16 +476,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." #endif -/* 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 +/* Define the interrupt disable/restore macros for each compiler. */ -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +#if defined(__GNUC__) || defined(__ICCARM__) -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; +/*** GCC/AC6 and IAR ***/ -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); #else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -static void _tx_thread_system_return_inline(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) { -unsigned int was_masked; +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (_ipsr == 0) { - was_masked = __disable_irq(); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); __enable_irq(); - if (was_masked != 0) + if (interrupt_save != 0) __disable_irq(); +#endif } } -#endif -/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline + +#else /* TX_DISABLE_INLINE is defined */ + +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -460,8 +719,8 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M3/AC5 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -470,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m3/ac5/inc/txm_module_port.h b/ports_module/cortex_m3/ac5/inc/txm_module_port.h index 523c787ab..ba34ddc8f 100644 --- a/ports_module/cortex_m3/ac5/inc/txm_module_port.h +++ b/ports_module/cortex_m3/ac5/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M3/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -44,6 +44,8 @@ /* 07-29-2022 Scott Larson Enabled user-defined and */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Configure heap size, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h: VOID (*tx_timer_module_expiration_function)(ULONG id); */ +/* Users can define the module heap size. */ +#ifndef TXM_MODULE_HEAP_SIZE +#define TXM_MODULE_HEAP_SIZE 512 +#endif + /* Define the kernel stack size for a module thread. */ #ifndef TXM_MODULE_KERNEL_STACK_SIZE #define TXM_MODULE_KERNEL_STACK_SIZE 768 diff --git a/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s index 118384707..b4772c4ff 100644 --- a/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m3/ac5/module_manager/src/tx_thread_schedule.s @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M3/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* fixed label syntax, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -324,11 +327,25 @@ __tx_ts_wait #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 @@ -411,11 +428,11 @@ __tx_ts_restore #ifdef TXM_MODULE_MPU_DEFAULT B config_mpu // configure MPU for module -default_mpu: +default_mpu LDR r0, =txm_module_default_mpu_registers // default MPU configuration #endif -config_mpu: +config_mpu LDM r0!,{r2-r9} // Load MPU regions 0-3 STM r1,{r2-r9} // Store MPU regions 0-3 LDM r0!,{r2-r9} // Load MPU regions 4-7 @@ -572,7 +589,7 @@ _tx_thread_user_return BIC r3, #1 // Clear LSPACT LDR r1, =0xE000EF34 // Address of FPCCR STR r3, [r1] // Save updated FPCCR -_tx_no_lazy_clear: +_tx_no_lazy_clear #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer diff --git a/ports_module/cortex_m3/ac6/inc/tx_port.h b/ports_module/cortex_m3/ac6/inc/tx_port.h index cd4ce994b..79177b2b8 100644 --- a/ports_module/cortex_m3/ac6/inc/tx_port.h +++ b/ports_module/cortex_m3/ac6/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M3/AC6 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M3 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); } +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); -#endif +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,133 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* 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. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -511,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M3/AC6 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S index 00ab90534..c4ebdb829 100644 --- a/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m3/ac6/module_manager/src/tx_thread_schedule.S @@ -42,7 +42,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M3/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m3/gnu/inc/tx_port.h b/ports_module/cortex_m3/gnu/inc/tx_port.h index b4197c967..79177b2b8 100644 --- a/ports_module/cortex_m3/gnu/inc/tx_port.h +++ b/ports_module/cortex_m3/gnu/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M3/GNU */ -/* 6.1.11 */ +/* tx_port.h Cortex-M3 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); } +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ -#endif +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,127 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -505,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M3/GNU Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S index a8b3894fa..627cc10ff 100644 --- a/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m3/gnu/module_manager/src/tx_thread_schedule.S @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M3/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m3/iar/inc/tx_port.h b/ports_module/cortex_m3/iar/inc/tx_port.h index 6ed2c1865..79177b2b8 100644 --- a/ports_module/cortex_m3/iar/inc/tx_port.h +++ b/ports_module/cortex_m3/iar/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M3/IAR */ -/* 6.1.11 */ +/* tx_port.h Cortex-M3 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,27 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include -#include -#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL #endif +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -88,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -115,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M3 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -166,7 +191,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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 @@ -180,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID); /* 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 + for the multiple macros is so that backward compatibility can be maintained with existing ThreadX kernel awareness modules. */ #define TX_THREAD_EXTENSION_0 @@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID *tx_thread_module_reserved; #endif #ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_3 #else #define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ unsigned long long tx_thread_execution_time_last_start; @@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -255,27 +280,26 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __ARMVFP__ +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -284,28 +308,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#endif +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -315,76 +382,76 @@ void _tx_misra_vfp_touch(void); #ifndef TX_MISRA_ENABLE -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -409,16 +476,38 @@ void _tx_misra_vfp_touch(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -427,92 +516,211 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* Determine if the ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." +#endif + + + +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif +} +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -/* 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. */ + int_posture = __get_interrupt_posture(); -#ifdef TX_DISABLE_INLINE +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); #else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif -#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);}; +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} static void _tx_thread_system_return_inline(void) { -__istate_t interrupt_save; +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) + if (_ipsr == 0) { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif } } -#endif +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -/* Define FPU extension for the Cortex-M3. Each is assumed to be called in the context of the executing - thread. These are no longer needed, but are preserved for backward compatibility only. */ +/*** End AC5 ***/ -void tx_thread_fpu_enable(void); -void tx_thread_fpu_disable(void); +#endif /* Interrupt disable/restore macros for each compiler. */ +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline -/* Define the interrupt lockout macros for each ThreadX object. */ +#else /* TX_DISABLE_INLINE is defined */ -#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 +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing + thread. These are no longer needed, but are preserved for backward compatibility only. */ + +void tx_thread_fpu_enable(void); +void tx_thread_fpu_disable(void); /* 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 Cortex-M3/IAR Version 6.1.10 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M3 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -521,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s index 53c60fbcd..ab3fef693 100644 --- a/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s +++ b/ports_module/cortex_m3/iar/module_manager/src/tx_misra.s @@ -102,12 +102,22 @@ PUBLIC _tx_misra_fpccr_get PUBLIC _tx_misra_vfp_touch #endif - PUBLIC _tx_version_id + PUBLIC _tx_misra_event_flags_group_not_used + PUBLIC _tx_misra_event_flags_set_notify_not_used + PUBLIC _tx_misra_queue_not_used + PUBLIC _tx_misra_queue_send_notify_not_used + PUBLIC _tx_misra_semaphore_not_used + PUBLIC _tx_misra_semaphore_put_notify_not_used + PUBLIC _tx_misra_thread_entry_exit_notify_not_used + PUBLIC _tx_misra_thread_not_used + +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA -// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; +// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; _tx_version_id: DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H @@ -115,11 +125,12 @@ _tx_version_id: DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H - DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H + DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ @@ -139,7 +150,7 @@ _tx_misra_memset: MOVS R1,R0 MOVS R0,R4 BL __aeabi_memset - POP {R4,PC} ;; return + POP {R4,PC} // return /**************************************************************************/ /**************************************************************************/ @@ -153,7 +164,7 @@ _tx_misra_memset: THUMB _tx_misra_uchar_pointer_add: ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add: _tx_misra_uchar_pointer_sub: RSBS R1,R1,#+0 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub: THUMB _tx_misra_uchar_pointer_dif: SUBS R0,R0,R1 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - + BX LR // return + + +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ +/** */ +/** This single function serves all of the below prototypes. */ +/** */ +/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ +/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ +/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ +/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ +/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ +/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ +/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ +/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ +/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ +/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ +/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ +/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ +/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ +/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ +/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ +/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ +/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ +/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ +/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ +/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ +/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ +/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ +/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ +/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */ +/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */ +/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */ +/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */ +/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */ +/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */ +/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */ +/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */ +/** */ +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_pointer_to_ulong_convert: - BX LR ;; return +_tx_misra_ulong_to_pointer_convert: +_tx_misra_indirect_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_indirect_uchar_pointer_convert: +_tx_misra_block_pool_to_uchar_pointer_convert: +_tx_misra_void_to_block_pool_pointer_convert: +_tx_misra_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_block_pool_pointer_convert: +_tx_misra_void_to_indirect_uchar_pointer_convert: +_tx_misra_void_to_byte_pool_pointer_convert: +_tx_misra_byte_pool_to_uchar_pointer_convert: +_tx_misra_uchar_to_align_type_pointer_convert: +_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: +_tx_misra_void_to_event_flags_pointer_convert: +_tx_misra_void_to_ulong_pointer_convert: +_tx_misra_void_to_mutex_pointer_convert: +_tx_misra_void_to_queue_pointer_convert: +_tx_misra_void_to_semaphore_pointer_convert: +_tx_misra_uchar_to_void_pointer_convert: +_tx_misra_ulong_to_thread_pointer_convert: +_tx_misra_timer_indirect_to_void_pointer_convert: +_tx_misra_const_char_to_char_pointer_convert: +_tx_misra_void_to_thread_pointer_convert: +#ifdef TX_ENABLE_EVENT_TRACE +_tx_misra_object_to_uchar_pointer_convert: +_tx_misra_uchar_to_object_pointer_convert: +_tx_misra_uchar_to_header_pointer_convert: +_tx_misra_uchar_to_entry_pointer_convert: +_tx_misra_entry_to_uchar_pointer_convert: +#endif +_tx_misra_char_to_uchar_pointer_convert: +_tx_misra_event_flags_group_not_used: +_tx_misra_event_flags_set_notify_not_used: +_tx_misra_queue_not_used: +_tx_misra_queue_send_notify_not_used: +_tx_misra_semaphore_not_used: +_tx_misra_semaphore_put_notify_not_used: +_tx_misra_thread_entry_exit_notify_not_used: +_tx_misra_thread_not_used: + + BX LR // return /**************************************************************************/ @@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert: THUMB _tx_misra_ulong_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub: MVNS R2,#+3 MULS R1,R2,R1 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub: _tx_misra_ulong_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -299,7 +372,7 @@ _tx_misra_message_copy: STR R3,[R0, #+0] STR R4,[R1, #+0] POP {R4,R5} - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -316,7 +389,7 @@ _tx_misra_message_copy: _tx_misra_timer_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif: THUMB _tx_misra_timer_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add: SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_user_timer_pointer_get: - ADDS R2,R0,#+8 - SUBS R2,R2,R0 - RSBS R2,R2,#+0 - ADD R0,R0,R2 - STR R0,[R1, #+0] - BX LR ;; return + SUBS R0,#8 + STR R0,[R1, #+0] + BX LR // return /**************************************************************************/ @@ -374,7 +444,7 @@ _tx_misra_thread_stack_check: CMP R4,#+0 BEQ.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+0] - LDR.N R2,??DataTable2 ;; 0x54485244 + LDR.N R2,??DataTable2 // 0x54485244 CMP R1,R2 BNE.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+8] @@ -412,7 +482,7 @@ _tx_misra_thread_stack_check: BL _tx_thread_interrupt_disable ??_tx_misra_thread_stack_check_0: BL _tx_thread_interrupt_restore - POP {R0,R4,R5,PC} ;; return + POP {R0,R4,R5,PC} // return #ifdef TX_ENABLE_EVENT_TRACE @@ -500,7 +570,7 @@ _tx_misra_trace_event_insert: LDR R0,[R0, #+0] STR R4,[R0, #+32] ??_tx_misra_trace_event_insert_0: - POP {R0,R4-R7,PC} ;; return + POP {R0,R4-R7,PC} // return SECTION `.text`:CODE:NOROOT(2) @@ -552,7 +622,7 @@ _tx_misra_trace_event_insert: THUMB _tx_misra_time_stamp_get: MOVS R0,#+0 - BX LR ;; return + BX LR // return #endif @@ -587,203 +657,7 @@ _tx_misra_time_stamp_get: THUMB _tx_misra_always_true: MOVS R0,#+1 - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_indirect_void_to_uchar_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/***********************************************************************************/ -/***********************************************************************************/ -/** */ -/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ -/** */ -/***********************************************************************************/ -/***********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_block_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_block_pool_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************/ -/************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************/ -/************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_block_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************/ -/**************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************/ -/**************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_byte_pool_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_byte_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_align_type_pointer_convert: - BX LR ;; return - - -/****************************************************************************************************/ -/****************************************************************************************************/ -/** */ -/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/****************************************************************************************************/ -/****************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************************/ -/**************************************************************************************************/ -/** */ -/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************************/ -/**************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_event_flags_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_ulong_pointer_convert: - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_mutex_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert: THUMB _tx_misra_status_get: MOVS R0,#+0 - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_queue_pointer_convert: - BX LR ;; return - - -/****************************************************************************************/ -/****************************************************************************************/ -/** */ -/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ -/** */ -/****************************************************************************************/ -/****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_semaphore_pointer_convert: - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_void_pointer_convert: - BX LR ;; return - - -/*********************************************************************************/ -/*********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ -/** */ -/*********************************************************************************/ -/*********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_thread_pointer_convert: - BX LR ;; return - - -/***************************************************************************************************/ -/***************************************************************************************************/ -/** */ -/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ -/** */ -/***************************************************************************************************/ -/***************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_timer_indirect_to_void_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_const_char_to_char_pointer_convert: - BX LR ;; return - - -/**********************************************************************************/ -/**********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ -/** */ -/**********************************************************************************/ -/**********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_thread_pointer_convert: - BX LR ;; return - - -#ifdef TX_ENABLE_EVENT_TRACE - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_object_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_object_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_header_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_entry_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_entry_to_uchar_pointer_convert: - BX LR ;; return -#endif - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_char_to_uchar_pointer_convert: - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert: THUMB _tx_misra_ipsr_get: MRS R0, IPSR - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1013,7 +702,7 @@ _tx_misra_ipsr_get: THUMB _tx_misra_control_get: MRS R0, CONTROL - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1028,7 +717,7 @@ _tx_misra_control_get: THUMB _tx_misra_control_set: MSR CONTROL, R0 - BX LR ;; return + BX LR // return #ifdef __ARMVFP__ @@ -1044,9 +733,9 @@ _tx_misra_control_set: SECTION `.text`:CODE:NOROOT(2) THUMB _tx_misra_fpccr_get: - LDR r0, =0xE000EF34 ; Build FPCCR address - LDR r0, [r0] ; Load FPCCR value - BX LR ;; return + LDR r0, =0xE000EF34 // Build FPCCR address + LDR r0, [r0] // Load FPCCR value + BX LR // return /***********************************************************************************************/ @@ -1061,7 +750,7 @@ _tx_misra_fpccr_get: THUMB _tx_misra_vfp_touch: vmov.f32 s0, s0 - BX LR ;; return + BX LR // return #endif diff --git a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s index b83ec5278..1ff11a25b 100644 --- a/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m3/iar/module_manager/src/tx_thread_schedule.s @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M3/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -77,6 +77,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -325,11 +327,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S index 417d14046..e305ca177 100644 --- a/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m33/ac6/module_manager/src/tx_thread_schedule.S @@ -30,7 +30,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M33/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -75,6 +75,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -344,11 +346,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S index af8be2baf..f8fb777b4 100644 --- a/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m33/gnu/module_manager/src/tx_thread_schedule.S @@ -29,7 +29,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M33/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -76,6 +76,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -345,11 +347,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s index 3242fac26..5cf5ae16f 100644 --- a/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m33/iar/module_manager/src/tx_thread_schedule.s @@ -42,7 +42,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M33/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -87,6 +87,8 @@ /* 07-29-2022 Scott Larson Removed the code path to skip */ /* MPU reloading, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -341,11 +343,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m4/ac5/inc/tx_port.h b/ports_module/cortex_m4/ac5/inc/tx_port.h index 3aba89f0d..73cb00690 100644 --- a/ports_module/cortex_m4/ac5/inc/tx_port.h +++ b/ports_module/cortex_m4/ac5/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M4/AC5 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M4 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M4 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,14 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifndef TX_MISRA_ENABLE -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -231,37 +308,72 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -270,78 +382,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -366,16 +476,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." #endif -/* 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 +/* Define the interrupt disable/restore macros for each compiler. */ -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +#if defined(__GNUC__) || defined(__ICCARM__) -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; +/*** GCC/AC6 and IAR ***/ -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); #else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -static void _tx_thread_system_return_inline(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) { -unsigned int was_masked; +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (_ipsr == 0) { - was_masked = __disable_irq(); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); __enable_irq(); - if (was_masked != 0) + if (interrupt_save != 0) __disable_irq(); +#endif } } -#endif -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline + +#else /* TX_DISABLE_INLINE is defined */ + +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -460,8 +719,8 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M4/AC5 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -470,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m4/ac5/inc/txm_module_port.h b/ports_module/cortex_m4/ac5/inc/txm_module_port.h index f375107e7..bddabbe3d 100644 --- a/ports_module/cortex_m4/ac5/inc/txm_module_port.h +++ b/ports_module/cortex_m4/ac5/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M4/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -44,6 +44,8 @@ /* 07-29-2022 Scott Larson Enabled user-defined and */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Configure heap size, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h: VOID (*tx_timer_module_expiration_function)(ULONG id); */ +/* Users can define the module heap size. */ +#ifndef TXM_MODULE_HEAP_SIZE +#define TXM_MODULE_HEAP_SIZE 512 +#endif + /* Define the kernel stack size for a module thread. */ #ifndef TXM_MODULE_KERNEL_STACK_SIZE #define TXM_MODULE_KERNEL_STACK_SIZE 768 diff --git a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s index 6067dd44d..3f59ee6cf 100644 --- a/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m4/ac5/module_manager/src/tx_thread_schedule.s @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M4/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* fixed label syntax, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -324,11 +327,25 @@ __tx_ts_wait #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 @@ -411,11 +428,11 @@ __tx_ts_restore #ifdef TXM_MODULE_MPU_DEFAULT B config_mpu // configure MPU for module -default_mpu: +default_mpu LDR r0, =txm_module_default_mpu_registers // default MPU configuration #endif -config_mpu: +config_mpu LDM r0!,{r2-r9} // Load MPU regions 0-3 STM r1,{r2-r9} // Store MPU regions 0-3 LDM r0!,{r2-r9} // Load MPU regions 4-7 @@ -572,7 +589,7 @@ _tx_thread_user_return BIC r3, #1 // Clear LSPACT LDR r1, =0xE000EF34 // Address of FPCCR STR r3, [r1] // Save updated FPCCR -_tx_no_lazy_clear: +_tx_no_lazy_clear #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer diff --git a/ports_module/cortex_m4/ac6/inc/tx_port.h b/ports_module/cortex_m4/ac6/inc/tx_port.h index 5e0f6a918..73cb00690 100644 --- a/ports_module/cortex_m4/ac6/inc/tx_port.h +++ b/ports_module/cortex_m4/ac6/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M4/AC6 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M4 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M4 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); } +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); -#endif +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,133 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* 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. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -511,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M4/AC6 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S index cb50426c9..9dfaee371 100644 --- a/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m4/ac6/module_manager/src/tx_thread_schedule.S @@ -42,7 +42,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M4/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S b/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S deleted file mode 100644 index d4cb16360..000000000 --- a/ports_module/cortex_m4/gnu/example_build/cortexm_crt0.S +++ /dev/null @@ -1,127 +0,0 @@ - .global _start - .extern main - - - .section .init, "ax" - .code 16 - .align 2 - .thumb_func - - -_start: - CPSID i - ldr r1, =__stack_end__ - mov sp, r1 - - - /* Copy initialised sections into RAM if required. */ - ldr r0, =__data_load_start__ - ldr r1, =__data_start__ - ldr r2, =__data_end__ - bl crt0_memory_copy - ldr r0, =__text_load_start__ - ldr r1, =__text_start__ - ldr r2, =__text_end__ - bl crt0_memory_copy - ldr r0, =__fast_load_start__ - ldr r1, =__fast_start__ - ldr r2, =__fast_end__ - bl crt0_memory_copy - ldr r0, =__ctors_load_start__ - ldr r1, =__ctors_start__ - ldr r2, =__ctors_end__ - bl crt0_memory_copy - ldr r0, =__dtors_load_start__ - ldr r1, =__dtors_start__ - ldr r2, =__dtors_end__ - bl crt0_memory_copy - ldr r0, =__rodata_load_start__ - ldr r1, =__rodata_start__ - ldr r2, =__rodata_end__ - bl crt0_memory_copy - - - /* Zero bss. */ - ldr r0, =__bss_start__ - ldr r1, =__bss_end__ - mov r2, #0 - bl crt0_memory_set - - - /* Setup heap - not recommended for Threadx but here for compatibility reasons */ - ldr r0, = __heap_start__ - ldr r1, = __heap_end__ - sub r1, r1, r0 - mov r2, #0 - str r2, [r0] - add r0, r0, #4 - str r1, [r0] - - - /* constructors in case of using C++ */ - ldr r0, =__ctors_start__ - ldr r1, =__ctors_end__ -crt0_ctor_loop: - cmp r0, r1 - beq crt0_ctor_end - ldr r2, [r0] - add r0, #4 - push {r0-r1} - blx r2 - pop {r0-r1} - b crt0_ctor_loop -crt0_ctor_end: - - - /* Setup call frame for main() */ - mov r0, #0 - mov lr, r0 - mov r12, sp - - -start: - /* Jump to main() */ - mov r0, #0 - mov r1, #0 - ldr r2, =main - blx r2 - /* when main returns, loop forever. */ -crt0_exit_loop: - b crt0_exit_loop - - - - /* Startup helper functions. */ - - -crt0_memory_copy: - cmp r0, r1 - beq memory_copy_done - sub r2, r2, r1 - beq memory_copy_done -memory_copy_loop: - ldrb r3, [r0] - add r0, r0, #1 - strb r3, [r1] - add r1, r1, #1 - sub r2, r2, #1 - bne memory_copy_loop -memory_copy_done: - bx lr - - -crt0_memory_set: - cmp r0, r1 - beq memory_set_done - strb r2, [r0] - add r0, r0, #1 - b crt0_memory_set -memory_set_done: - bx lr - - - /* Setup attibutes of stack and heap sections so they don't take up room in the elf file */ - .section .stack, "wa", %nobits - .section .stack_process, "wa", %nobits - .section .heap, "wa", %nobits - \ No newline at end of file diff --git a/ports_module/cortex_m4/gnu/inc/tx_port.h b/ports_module/cortex_m4/gnu/inc/tx_port.h index ed3f09840..73cb00690 100644 --- a/ports_module/cortex_m4/gnu/inc/tx_port.h +++ b/ports_module/cortex_m4/gnu/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M4/GNU */ -/* 6.1.11 */ +/* tx_port.h Cortex-M4 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M4 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); } +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ -#endif +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,127 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -505,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M4/GNU Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S index 4d5e99470..43cd3725a 100644 --- a/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m4/gnu/module_manager/src/tx_thread_schedule.S @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M4/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m4/iar/inc/tx_port.h b/ports_module/cortex_m4/iar/inc/tx_port.h index 2f620957d..73cb00690 100644 --- a/ports_module/cortex_m4/iar/inc/tx_port.h +++ b/ports_module/cortex_m4/iar/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M4/IAR */ -/* 6.1.11 */ +/* tx_port.h Cortex-M4 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,27 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include -#include -#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL #endif +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -88,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -115,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M4 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -166,7 +191,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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 @@ -180,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID); /* 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 + for the multiple macros is so that backward compatibility can be maintained with existing ThreadX kernel awareness modules. */ #define TX_THREAD_EXTENSION_0 @@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID *tx_thread_module_reserved; #endif #ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_3 #else #define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ unsigned long long tx_thread_execution_time_last_start; @@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -255,27 +280,26 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __ARMVFP__ +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -284,28 +308,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#endif +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -315,76 +382,76 @@ void _tx_misra_vfp_touch(void); #ifndef TX_MISRA_ENABLE -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -409,16 +476,38 @@ void _tx_misra_vfp_touch(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -427,92 +516,211 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* Determine if the ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." +#endif + + + +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif +} +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -/* 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. */ + int_posture = __get_interrupt_posture(); -#ifdef TX_DISABLE_INLINE +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); #else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif -#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);}; +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} static void _tx_thread_system_return_inline(void) { -__istate_t interrupt_save; +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) + if (_ipsr == 0) { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif } } -#endif +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -/* Define FPU extension for the Cortex-M4. Each is assumed to be called in the context of the executing - thread. These are no longer needed, but are preserved for backward compatibility only. */ +/*** End AC5 ***/ -void tx_thread_fpu_enable(void); -void tx_thread_fpu_disable(void); +#endif /* Interrupt disable/restore macros for each compiler. */ +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline -/* Define the interrupt lockout macros for each ThreadX object. */ +#else /* TX_DISABLE_INLINE is defined */ -#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 +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing + thread. These are no longer needed, but are preserved for backward compatibility only. */ + +void tx_thread_fpu_enable(void); +void tx_thread_fpu_disable(void); /* 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 Cortex-M4/IAR Version 6.1.10 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M4 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -521,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s index 53c60fbcd..ab3fef693 100644 --- a/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s +++ b/ports_module/cortex_m4/iar/module_manager/src/tx_misra.s @@ -102,12 +102,22 @@ PUBLIC _tx_misra_fpccr_get PUBLIC _tx_misra_vfp_touch #endif - PUBLIC _tx_version_id + PUBLIC _tx_misra_event_flags_group_not_used + PUBLIC _tx_misra_event_flags_set_notify_not_used + PUBLIC _tx_misra_queue_not_used + PUBLIC _tx_misra_queue_send_notify_not_used + PUBLIC _tx_misra_semaphore_not_used + PUBLIC _tx_misra_semaphore_put_notify_not_used + PUBLIC _tx_misra_thread_entry_exit_notify_not_used + PUBLIC _tx_misra_thread_not_used + +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA -// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; +// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; _tx_version_id: DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H @@ -115,11 +125,12 @@ _tx_version_id: DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H - DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H + DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ @@ -139,7 +150,7 @@ _tx_misra_memset: MOVS R1,R0 MOVS R0,R4 BL __aeabi_memset - POP {R4,PC} ;; return + POP {R4,PC} // return /**************************************************************************/ /**************************************************************************/ @@ -153,7 +164,7 @@ _tx_misra_memset: THUMB _tx_misra_uchar_pointer_add: ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add: _tx_misra_uchar_pointer_sub: RSBS R1,R1,#+0 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub: THUMB _tx_misra_uchar_pointer_dif: SUBS R0,R0,R1 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - + BX LR // return + + +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ +/** */ +/** This single function serves all of the below prototypes. */ +/** */ +/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ +/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ +/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ +/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ +/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ +/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ +/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ +/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ +/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ +/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ +/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ +/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ +/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ +/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ +/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ +/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ +/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ +/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ +/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ +/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ +/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ +/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ +/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ +/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */ +/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */ +/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */ +/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */ +/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */ +/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */ +/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */ +/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */ +/** */ +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_pointer_to_ulong_convert: - BX LR ;; return +_tx_misra_ulong_to_pointer_convert: +_tx_misra_indirect_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_indirect_uchar_pointer_convert: +_tx_misra_block_pool_to_uchar_pointer_convert: +_tx_misra_void_to_block_pool_pointer_convert: +_tx_misra_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_block_pool_pointer_convert: +_tx_misra_void_to_indirect_uchar_pointer_convert: +_tx_misra_void_to_byte_pool_pointer_convert: +_tx_misra_byte_pool_to_uchar_pointer_convert: +_tx_misra_uchar_to_align_type_pointer_convert: +_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: +_tx_misra_void_to_event_flags_pointer_convert: +_tx_misra_void_to_ulong_pointer_convert: +_tx_misra_void_to_mutex_pointer_convert: +_tx_misra_void_to_queue_pointer_convert: +_tx_misra_void_to_semaphore_pointer_convert: +_tx_misra_uchar_to_void_pointer_convert: +_tx_misra_ulong_to_thread_pointer_convert: +_tx_misra_timer_indirect_to_void_pointer_convert: +_tx_misra_const_char_to_char_pointer_convert: +_tx_misra_void_to_thread_pointer_convert: +#ifdef TX_ENABLE_EVENT_TRACE +_tx_misra_object_to_uchar_pointer_convert: +_tx_misra_uchar_to_object_pointer_convert: +_tx_misra_uchar_to_header_pointer_convert: +_tx_misra_uchar_to_entry_pointer_convert: +_tx_misra_entry_to_uchar_pointer_convert: +#endif +_tx_misra_char_to_uchar_pointer_convert: +_tx_misra_event_flags_group_not_used: +_tx_misra_event_flags_set_notify_not_used: +_tx_misra_queue_not_used: +_tx_misra_queue_send_notify_not_used: +_tx_misra_semaphore_not_used: +_tx_misra_semaphore_put_notify_not_used: +_tx_misra_thread_entry_exit_notify_not_used: +_tx_misra_thread_not_used: + + BX LR // return /**************************************************************************/ @@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert: THUMB _tx_misra_ulong_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub: MVNS R2,#+3 MULS R1,R2,R1 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub: _tx_misra_ulong_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -299,7 +372,7 @@ _tx_misra_message_copy: STR R3,[R0, #+0] STR R4,[R1, #+0] POP {R4,R5} - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -316,7 +389,7 @@ _tx_misra_message_copy: _tx_misra_timer_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif: THUMB _tx_misra_timer_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add: SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_user_timer_pointer_get: - ADDS R2,R0,#+8 - SUBS R2,R2,R0 - RSBS R2,R2,#+0 - ADD R0,R0,R2 - STR R0,[R1, #+0] - BX LR ;; return + SUBS R0,#8 + STR R0,[R1, #+0] + BX LR // return /**************************************************************************/ @@ -374,7 +444,7 @@ _tx_misra_thread_stack_check: CMP R4,#+0 BEQ.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+0] - LDR.N R2,??DataTable2 ;; 0x54485244 + LDR.N R2,??DataTable2 // 0x54485244 CMP R1,R2 BNE.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+8] @@ -412,7 +482,7 @@ _tx_misra_thread_stack_check: BL _tx_thread_interrupt_disable ??_tx_misra_thread_stack_check_0: BL _tx_thread_interrupt_restore - POP {R0,R4,R5,PC} ;; return + POP {R0,R4,R5,PC} // return #ifdef TX_ENABLE_EVENT_TRACE @@ -500,7 +570,7 @@ _tx_misra_trace_event_insert: LDR R0,[R0, #+0] STR R4,[R0, #+32] ??_tx_misra_trace_event_insert_0: - POP {R0,R4-R7,PC} ;; return + POP {R0,R4-R7,PC} // return SECTION `.text`:CODE:NOROOT(2) @@ -552,7 +622,7 @@ _tx_misra_trace_event_insert: THUMB _tx_misra_time_stamp_get: MOVS R0,#+0 - BX LR ;; return + BX LR // return #endif @@ -587,203 +657,7 @@ _tx_misra_time_stamp_get: THUMB _tx_misra_always_true: MOVS R0,#+1 - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_indirect_void_to_uchar_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/***********************************************************************************/ -/***********************************************************************************/ -/** */ -/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ -/** */ -/***********************************************************************************/ -/***********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_block_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_block_pool_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************/ -/************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************/ -/************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_block_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************/ -/**************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************/ -/**************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_byte_pool_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_byte_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_align_type_pointer_convert: - BX LR ;; return - - -/****************************************************************************************************/ -/****************************************************************************************************/ -/** */ -/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/****************************************************************************************************/ -/****************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************************/ -/**************************************************************************************************/ -/** */ -/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************************/ -/**************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_event_flags_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_ulong_pointer_convert: - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_mutex_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert: THUMB _tx_misra_status_get: MOVS R0,#+0 - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_queue_pointer_convert: - BX LR ;; return - - -/****************************************************************************************/ -/****************************************************************************************/ -/** */ -/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ -/** */ -/****************************************************************************************/ -/****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_semaphore_pointer_convert: - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_void_pointer_convert: - BX LR ;; return - - -/*********************************************************************************/ -/*********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ -/** */ -/*********************************************************************************/ -/*********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_thread_pointer_convert: - BX LR ;; return - - -/***************************************************************************************************/ -/***************************************************************************************************/ -/** */ -/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ -/** */ -/***************************************************************************************************/ -/***************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_timer_indirect_to_void_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_const_char_to_char_pointer_convert: - BX LR ;; return - - -/**********************************************************************************/ -/**********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ -/** */ -/**********************************************************************************/ -/**********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_thread_pointer_convert: - BX LR ;; return - - -#ifdef TX_ENABLE_EVENT_TRACE - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_object_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_object_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_header_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_entry_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_entry_to_uchar_pointer_convert: - BX LR ;; return -#endif - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_char_to_uchar_pointer_convert: - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert: THUMB _tx_misra_ipsr_get: MRS R0, IPSR - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1013,7 +702,7 @@ _tx_misra_ipsr_get: THUMB _tx_misra_control_get: MRS R0, CONTROL - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1028,7 +717,7 @@ _tx_misra_control_get: THUMB _tx_misra_control_set: MSR CONTROL, R0 - BX LR ;; return + BX LR // return #ifdef __ARMVFP__ @@ -1044,9 +733,9 @@ _tx_misra_control_set: SECTION `.text`:CODE:NOROOT(2) THUMB _tx_misra_fpccr_get: - LDR r0, =0xE000EF34 ; Build FPCCR address - LDR r0, [r0] ; Load FPCCR value - BX LR ;; return + LDR r0, =0xE000EF34 // Build FPCCR address + LDR r0, [r0] // Load FPCCR value + BX LR // return /***********************************************************************************************/ @@ -1061,7 +750,7 @@ _tx_misra_fpccr_get: THUMB _tx_misra_vfp_touch: vmov.f32 s0, s0 - BX LR ;; return + BX LR // return #endif diff --git a/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s index 8291f3341..2a1761c1a 100644 --- a/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m4/iar/module_manager/src/tx_thread_schedule.s @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M4/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -77,6 +77,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -325,11 +327,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m7/ac5/inc/tx_port.h b/ports_module/cortex_m7/ac5/inc/tx_port.h index 9aca7f4b1..1b6fa4fb3 100644 --- a/ports_module/cortex_m7/ac5/inc/tx_port.h +++ b/ports_module/cortex_m7/ac5/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M7/AC5 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M7 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,14 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifndef TX_MISRA_ENABLE -register unsigned int _ipsr __asm("ipsr"); +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif -#ifdef __TARGET_FPU_VFP +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -231,37 +308,72 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -#ifdef TX_SOURCE_CODE +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ -register ULONG _control __asm("control"); +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ -#endif -#endif /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -270,78 +382,76 @@ register ULONG _control __asm("control"); #ifndef TX_MISRA_ENABLE -void _tx_vfp_access(void); - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_vfp_access(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _control; \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _control = _tx_vfp_state; \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -366,16 +476,38 @@ void _tx_vfp_access(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) -#else + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -387,70 +519,197 @@ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE - -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." #endif -/* 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 +/* Define the interrupt disable/restore macros for each compiler. */ -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +#if defined(__GNUC__) || defined(__ICCARM__) -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; +/*** GCC/AC6 and IAR ***/ -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); #else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif +} -#define TX_INTERRUPT_SAVE_AREA UINT was_masked; -#define TX_DISABLE was_masked = __disable_irq(); -#define TX_RESTORE if (was_masked == 0) __enable_irq(); +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -static void _tx_thread_system_return_inline(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif + +static __inline unsigned int __disable_interrupts(void) { -unsigned int was_masked; +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} +static void _tx_thread_system_return_inline(void) +{ +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (_ipsr == 0) { - was_masked = __disable_irq(); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); __enable_irq(); - if (was_masked != 0) + if (interrupt_save != 0) __disable_irq(); +#endif } } -#endif -/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); + +/*** End AC5 ***/ + +#endif /* Interrupt disable/restore macros for each compiler. */ + +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline + +#else /* TX_DISABLE_INLINE is defined */ + +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -460,8 +719,8 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M7/AC5 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -470,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m7/ac5/inc/txm_module_port.h b/ports_module/cortex_m7/ac5/inc/txm_module_port.h index 3ac5acf76..ae4bdf24c 100644 --- a/ports_module/cortex_m7/ac5/inc/txm_module_port.h +++ b/ports_module/cortex_m7/ac5/inc/txm_module_port.h @@ -26,7 +26,7 @@ /* APPLICATION INTERFACE DEFINITION RELEASE */ /* */ /* txm_module_port.h Cortex-M7/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -44,6 +44,8 @@ /* 07-29-2022 Scott Larson Enabled user-defined and */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Configure heap size, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -94,6 +96,11 @@ The following extensions must also be defined in tx_port.h: VOID (*tx_timer_module_expiration_function)(ULONG id); */ +/* Users can define the module heap size. */ +#ifndef TXM_MODULE_HEAP_SIZE +#define TXM_MODULE_HEAP_SIZE 512 +#endif + /* Define the kernel stack size for a module thread. */ #ifndef TXM_MODULE_KERNEL_STACK_SIZE #define TXM_MODULE_KERNEL_STACK_SIZE 768 diff --git a/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s index 21b92ae79..95870c575 100644 --- a/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m7/ac5/module_manager/src/tx_thread_schedule.s @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/AC5 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -80,6 +80,9 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* fixed label syntax, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -324,11 +327,25 @@ __tx_ts_wait #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 @@ -411,11 +428,11 @@ __tx_ts_restore #ifdef TXM_MODULE_MPU_DEFAULT B config_mpu // configure MPU for module -default_mpu: +default_mpu LDR r0, =txm_module_default_mpu_registers // default MPU configuration #endif -config_mpu: +config_mpu LDM r0!,{r2-r9} // Load MPU regions 0-3 STM r1,{r2-r9} // Store MPU regions 0-3 LDM r0!,{r2-r9} // Load MPU regions 4-7 @@ -572,7 +589,7 @@ _tx_thread_user_return BIC r3, #1 // Clear LSPACT LDR r1, =0xE000EF34 // Address of FPCCR STR r3, [r1] // Save updated FPCCR -_tx_no_lazy_clear: +_tx_no_lazy_clear #endif LDR r0, [r2, #0xB0] // Load the module thread stack pointer diff --git a/ports_module/cortex_m7/ac6/inc/tx_port.h b/ports_module/cortex_m7/ac6/inc/tx_port.h index 56f2531fc..1b6fa4fb3 100644 --- a/ports_module/cortex_m7/ac6/inc/tx_port.h +++ b/ports_module/cortex_m7/ac6/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M7/AC6 */ -/* 6.1.11 */ +/* tx_port.h Cortex-M7 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); } +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); -#endif +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,133 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* 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. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -511,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M7/AC6 Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S index 7111ccf18..a7261d41a 100644 --- a/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m7/ac6/module_manager/src/tx_thread_schedule.S @@ -42,7 +42,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/AC6 */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m7/gnu/inc/tx_port.h b/ports_module/cortex_m7/gnu/inc/tx_port.h index 0d9feee79..1b6fa4fb3 100644 --- a/ports_module/cortex_m7/gnu/inc/tx_port.h +++ b/ports_module/cortex_m7/gnu/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M7/GNU */ -/* 6.1.11 */ +/* tx_port.h Cortex-M7 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,23 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL +#endif + +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -84,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -111,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -131,9 +160,15 @@ typedef unsigned short USHORT; */ +#ifndef TX_MISRA_ENABLE #ifndef TX_TRACE_TIME_SOURCE #define TX_TRACE_TIME_SOURCE *((volatile ULONG *) 0xE0001004) #endif +#else +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif + #ifndef TX_TRACE_TIME_MASK #define TX_TRACE_TIME_MASK 0xFFFFFFFFUL #endif @@ -149,26 +184,48 @@ typedef unsigned short USHORT; initialization capabilities can prevent their initialization from being a function call. */ +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else #define TX_INLINE_INITIALIZATION +#endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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. */ +#ifndef TX_MISRA_ENABLE #ifdef TX_ENABLE_STACK_CHECKING #undef TX_DISABLE_STACK_FILLING #endif +#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 + 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 +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ + VOID *tx_thread_module_entry_info_ptr; \ + ULONG tx_thread_module_current_user_mode; \ + ULONG tx_thread_module_user_mode; \ + ULONG tx_thread_module_saved_lr; \ + VOID *tx_thread_module_kernel_stack_start; \ + VOID *tx_thread_module_kernel_stack_end; \ + ULONG tx_thread_module_kernel_stack_size; \ + VOID *tx_thread_module_stack_ptr; \ + VOID *tx_thread_module_stack_start; \ + VOID *tx_thread_module_stack_end; \ + ULONG tx_thread_module_stack_size; \ + VOID *tx_thread_module_reserved; \ + VOID *tx_thread_iar_tls_pointer; +#else #define TX_THREAD_EXTENSION_2 VOID *tx_thread_module_instance_ptr; \ VOID *tx_thread_module_entry_info_ptr; \ ULONG tx_thread_module_current_user_mode; \ @@ -182,7 +239,13 @@ typedef unsigned short USHORT; VOID *tx_thread_module_stack_end; \ ULONG tx_thread_module_stack_size; \ VOID *tx_thread_module_reserved; +#endif +#ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY #define TX_THREAD_EXTENSION_3 +#else +#define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ + unsigned long long tx_thread_execution_time_last_start; +#endif /* Define the port extensions of the remaining ThreadX objects. */ @@ -203,11 +266,11 @@ typedef unsigned short USHORT; VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -215,11 +278,28 @@ typedef unsigned short USHORT; tx_thread_shell_entry, and tx_thread_terminate. */ -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) - -#ifdef TX_ENABLE_FPU_SUPPORT +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT +#if (__VER__ < 8000000) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); +#else +void *_tx_iar_create_per_thread_tls_area(void); +void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); +void __iar_Initlocks(void); + +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#endif +#else +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#endif +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -228,26 +308,49 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#else +#else /* TX_MISRA_ENABLE not defined */ -__attribute__( ( always_inline ) ) static inline ULONG __get_control(void) -{ +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ ULONG control_value; __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); return(control_value); } +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ -__attribute__( ( always_inline ) ) static inline void __set_control(ULONG control_value) +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) { +ULONG control_value; - __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); } +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ -#endif +#endif /* TX_MISRA_ENABLE */ /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA @@ -255,23 +358,22 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - -#endif +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } +#endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. If so, deactivate the FPU via CONTROL.FPCA. Otherwise we are in an interrupt or another thread is terminating @@ -280,77 +382,76 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #ifndef TX_MISRA_ENABLE - -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm__ volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_control(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_control(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -375,127 +476,240 @@ __attribute__( ( always_inline ) ) static inline void __set_control(ULONG contro #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + __attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) { - unsigned int ipsr_value; - __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); return(ipsr_value); } - #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) -#else + +#elif defined(__ICCARM__) /* IAR */ + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value - indicates that _tx_thread_system_return should not be called. */ + indicates that _tx_thread_system_return should not be called. This overrides the definition in tx_thread.h + for Cortex-M since so we don't waste time checking the _tx_thread_system_state variable that is always + zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK #define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* This ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ #define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); - +#else +#error "Compiler not supported." #endif -#ifndef TX_DISABLE_INLINE -/* Define GNU specific macros, with in-line assembly for performance. */ +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ -__attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) { +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} -unsigned int primask_value; +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - __asm__ volatile (" CPSID i" : : : "memory" ); - return(primask_value); +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); +#endif } -__attribute__( ( always_inline ) ) static inline void __restore_interrupts(unsigned int primask_value) +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) { +UINT int_posture; - __asm__ volatile (" MSR PRIMASK,%0": : "r" (primask_value): "memory" ); + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); } -__attribute__( ( always_inline ) ) static inline unsigned int __get_primask_value(void) +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) { +UINT interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} + +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -unsigned int primask_value; +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) + +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); +#else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} - __asm__ volatile (" MRS %0,PRIMASK ": "=r" (primask_value) ); - return(primask_value); +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); } +#endif -__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +static __inline unsigned int __disable_interrupts(void) { +unsigned int int_posture; + + int_posture = __get_interrupt_posture(); - __asm__ volatile (" CPSIE i": : : "memory" ); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); } +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} -__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +static void _tx_thread_system_return_inline(void) { unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_ipsr_value() == 0) + if (_ipsr == 0) { - interrupt_save = __get_primask_value(); - __enable_interrupts(); - __restore_interrupts(interrupt_save); - } +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif + } } #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_DISABLE interrupt_save = __disable_interrupts(); -#define TX_RESTORE __restore_interrupts(interrupt_save); +/*** End AC5 ***/ +#endif /* Interrupt disable/restore macros for each compiler. */ /* Redefine _tx_thread_system_return for improved performance. */ - #define _tx_thread_system_return _tx_thread_system_return_inline +#else /* TX_DISABLE_INLINE is defined */ -#else +UINT _tx_thread_interrupt_disable(VOID); +VOID _tx_thread_interrupt_restore(UINT previous_posture); -#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_control(TX_INT_DISABLE); -#define TX_RESTORE _tx_thread_interrupt_control(interrupt_save); -#endif +#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +#endif /* TX_DISABLE_INLINE */ -/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing thread. These are no longer needed, but are preserved for backward compatibility only. */ void tx_thread_fpu_enable(void); @@ -505,11 +719,14 @@ void tx_thread_fpu_disable(void); /* 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 Cortex-M7/GNU Version 6.1.11 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *"; +#else +#ifdef TX_MISRA_ENABLE +extern CHAR _tx_version_id[100]; #else extern CHAR _tx_version_id[]; #endif - +#endif #endif diff --git a/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S index 69cb74bb5..8d28f92da 100644 --- a/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_module/cortex_m7/gnu/module_manager/src/tx_thread_schedule.S @@ -40,7 +40,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/GNU */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -82,6 +82,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -337,11 +339,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_module/cortex_m7/iar/inc/tx_port.h b/ports_module/cortex_m7/iar/inc/tx_port.h index 70975f91b..1b6fa4fb3 100644 --- a/ports_module/cortex_m7/iar/inc/tx_port.h +++ b/ports_module/cortex_m7/iar/inc/tx_port.h @@ -25,12 +25,12 @@ /* */ /* PORT SPECIFIC C INFORMATION RELEASE */ /* */ -/* tx_port.h Cortex-M7/IAR */ -/* 6.1.11 */ +/* tx_port.h Cortex-M7 */ +/* 6.2.0 */ /* */ /* AUTHOR */ /* */ -/* William E. Lamie, Microsoft Corporation */ +/* Scott Larson, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ @@ -43,6 +43,9 @@ /* own special types that can be mapped to actual data types by this */ /* file to guarantee consistency in the interface and functionality. */ /* */ +/* This file replaces the previous Cortex-M3/M4/M7 files. It unifies */ +/* the ARMv7-M architecture and compilers into one common file. */ +/* */ /* RELEASE HISTORY */ /* */ /* DATE NAME DESCRIPTION */ @@ -57,27 +60,42 @@ #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 +/* 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 - +#endif /* TX_INCLUDE_USER_DEFINE_FILE */ /* Define compiler library include files. */ #include #include -#include -#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT + +#ifdef __ICCARM__ +#include /* IAR Intrinsics */ +#define __asm__ __asm /* Define to make all inline asm look similar */ +#ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #include +#endif /* TX_ENABLE_IAR_LIBRARY_SUPPORT */ +#endif /* __ICCARM__ */ + +#ifdef __ghs__ +#include +#include "tx_ghs.h" +#endif /* __ghs__ */ + + +#if !defined(__GNUC__) && !defined(__CC_ARM) +#define __get_control_value __get_CONTROL +#define __set_control_value __set_CONTROL #endif +#ifndef __GNUC__ +#define __get_ipsr_value __get_IPSR +#endif /* Define ThreadX basic types for this port. */ @@ -88,9 +106,10 @@ typedef int INT; typedef unsigned int UINT; typedef long LONG; typedef unsigned long ULONG; +typedef unsigned long long ULONG64; typedef short SHORT; typedef unsigned short USHORT; - +#define ULONG64_DEFINED /* Define the priority levels for ThreadX. Legal values range from 32 to 1024 and MUST be evenly divisible by 32. */ @@ -115,19 +134,25 @@ typedef unsigned short USHORT; #define TX_TIMER_THREAD_STACK_SIZE 1024 /* Default timer thread stack size */ #endif -#ifndef TX_TIMER_THREAD_PRIORITY +#ifndef TX_TIMER_THREAD_PRIORITY #define TX_TIMER_THREAD_PRIORITY 0 /* Default timer thread priority */ #endif +/* By default, ThreadX for Cortex-M uses the PRIMASK register to enable/disable interrupts. +If using BASEPRI is desired, define the following two symbols for both c and assembly files: +TX_PORT_USE_BASEPRI - This tells ThreadX to use BASEPRI instead of PRIMASK. +TX_PORT_BASEPRI = (priority_mask << (8 - number_priority_bits)) - this defines the maximum priority level to mask. +Any interrupt with a higher priority than priority_mask will not be masked, thus the interrupt will run. +*/ -/* Define various constants for the ThreadX Cortex-M7 port. */ +/* Define various constants for the ThreadX Cortex-M port. */ #define TX_INT_DISABLE 1 /* Disable interrupts */ #define TX_INT_ENABLE 0 /* Enable interrupts */ -/* 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 +/* 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 *((volatile ULONG *) 0x0a800024) @@ -166,7 +191,7 @@ ULONG _tx_misra_time_stamp_get(VOID); #endif -/* Determine whether or not stack checking is enabled. By default, ThreadX stack checking is +/* 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 @@ -180,7 +205,7 @@ ULONG _tx_misra_time_stamp_get(VOID); /* 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 + for the multiple macros is so that backward compatibility can be maintained with existing ThreadX kernel awareness modules. */ #define TX_THREAD_EXTENSION_0 @@ -216,7 +241,7 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID *tx_thread_module_reserved; #endif #ifndef TX_ENABLE_EXECUTION_CHANGE_NOTIFY -#define TX_THREAD_EXTENSION_3 +#define TX_THREAD_EXTENSION_3 #else #define TX_THREAD_EXTENSION_3 unsigned long long tx_thread_execution_time_total; \ unsigned long long tx_thread_execution_time_last_start; @@ -241,11 +266,11 @@ ULONG _tx_misra_time_stamp_get(VOID); VOID (*tx_timer_module_expiration_function)(ULONG id); -/* Define the user extension field of the thread control block. Nothing +/* 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 +#define TX_THREAD_USER_EXTENSION #endif @@ -255,27 +280,26 @@ ULONG _tx_misra_time_stamp_get(VOID); #ifdef TX_ENABLE_IAR_LIBRARY_SUPPORT #if (__VER__ < 8000000) -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = __iar_dlib_perthread_allocate(); #define TX_THREAD_DELETE_EXTENSION(thread_ptr) __iar_dlib_perthread_deallocate(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; #define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION __iar_dlib_perthread_access(0); #else void *_tx_iar_create_per_thread_tls_area(void); void _tx_iar_destroy_per_thread_tls_area(void *tls_ptr); void __iar_Initlocks(void); -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ - thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); -#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) thread_ptr -> tx_thread_iar_tls_pointer = _tx_iar_create_per_thread_tls_area(); +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) do {_tx_iar_destroy_per_thread_tls_area(thread_ptr -> tx_thread_iar_tls_pointer); \ + thread_ptr -> tx_thread_iar_tls_pointer = TX_NULL; } while(0); +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION do {__iar_Initlocks();} while(0); #endif #else -#define TX_THREAD_CREATE_EXTENSION(thread_ptr) -#define TX_THREAD_DELETE_EXTENSION(thread_ptr) +#define TX_THREAD_CREATE_EXTENSION(thread_ptr) +#define TX_THREAD_DELETE_EXTENSION(thread_ptr) #endif - -#ifdef __ARMVFP__ +#if defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) #ifdef TX_MISRA_ENABLE @@ -284,28 +308,71 @@ void _tx_misra_control_set(ULONG value); ULONG _tx_misra_fpccr_get(void); void _tx_misra_vfp_touch(void); -#endif +#else /* TX_MISRA_ENABLE not defined */ + +/* Define some helper functions (these are intrinsics in some compilers). */ +#ifdef __GNUC__ /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm__ volatile (" MRS %0,CONTROL ": "=r" (control_value) ); + return(control_value); +} + +__attribute__( ( always_inline ) ) static inline void __set_control_value(ULONG control_value) +{ + __asm__ volatile (" MSR CONTROL,%0": : "r" (control_value): "memory" ); +} + +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); + +#elif defined(__CC_ARM) /* ARM Compiler 5 */ + +__attribute__( ( always_inline ) ) ULONG __get_control_value(void) +{ +ULONG control_value; + + __asm volatile ("MRS control_value,CONTROL"); + return(control_value); +} + +__attribute__( ( always_inline ) ) void __set_control_value(ULONG control_value) +{ + __asm__ volatile ("MSR CONTROL,control_value"); +} +/* Can't access VFP registers with inline asm, so define this in tx_thread_schedule. */ +void _tx_vfp_access(void); +#define TX_VFP_TOUCH() _tx_vfp_access(); + +#elif defined(__ICCARM__) /* IAR */ +#define TX_VFP_TOUCH() __asm__ volatile ("VMOV.F32 s0, s0"); +#endif /* Helper functions for different compilers */ + +#endif /* TX_MISRA_ENABLE */ + /* A completed thread falls into _thread_shell_entry and we can simply deactivate the FPU via CONTROL.FPCA in order to ensure no lazy stacking will occur. */ #ifndef TX_MISRA_ENABLE -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } #else -#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } - +#define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } + #endif /* A thread can be terminated by another thread, so we first check if it's self-terminating and not in an ISR. @@ -315,76 +382,76 @@ void _tx_misra_vfp_touch(void); #ifndef TX_MISRA_ENABLE -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - __asm volatile ("vmov.f32 s0, s0"); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = __get_CONTROL(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - __set_CONTROL(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = *((volatile ULONG *) 0xE000EF34); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + TX_VFP_TOUCH(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = __get_control_value(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + __set_control_value(_tx_vfp_state); \ + } \ + } \ + } \ + } #else -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ - ULONG _tx_system_state; \ - _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ - if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - else \ - { \ - ULONG _tx_fpccr; \ - _tx_fpccr = _tx_misra_fpccr_get(); \ - _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ - if (_tx_fpccr == ((ULONG) 0x01)) \ - { \ - ULONG _tx_vfp_state; \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ - _tx_misra_vfp_touch(); \ - if (_tx_vfp_state == ((ULONG) 0)) \ - { \ - _tx_vfp_state = _tx_misra_control_get(); \ - _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ - _tx_misra_control_set(_tx_vfp_state); \ - } \ - } \ - } \ - } +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) { \ + ULONG _tx_system_state; \ + _tx_system_state = TX_THREAD_GET_SYSTEM_STATE(); \ + if ((_tx_system_state == ((ULONG) 0)) && ((thread_ptr) == _tx_thread_current_ptr)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + else \ + { \ + ULONG _tx_fpccr; \ + _tx_fpccr = _tx_misra_fpccr_get(); \ + _tx_fpccr = _tx_fpccr & ((ULONG) 0x01); \ + if (_tx_fpccr == ((ULONG) 0x01)) \ + { \ + ULONG _tx_vfp_state; \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ((ULONG) 0x4); \ + _tx_misra_vfp_touch(); \ + if (_tx_vfp_state == ((ULONG) 0)) \ + { \ + _tx_vfp_state = _tx_misra_control_get(); \ + _tx_vfp_state = _tx_vfp_state & ~((ULONG) 0x4); \ + _tx_misra_control_set(_tx_vfp_state); \ + } \ + } \ + } \ + } #endif -#else +#else /* No VFP in use */ #define TX_THREAD_COMPLETED_EXTENSION(thread_ptr) -#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) +#define TX_THREAD_TERMINATED_EXTENSION(thread_ptr) -#endif +#endif /* defined(__ARMVFP__) || defined(__ARM_PCS_VFP) || defined(__ARM_FP) || defined(__TARGET_FPU_VFP) || defined(__VFP__) */ /* Define the ThreadX object creation extensions for the remaining objects. */ @@ -409,16 +476,38 @@ void _tx_misra_vfp_touch(void); #define TX_TIMER_DELETE_EXTENSION(timer_ptr) -/* Define the get system state macro. */ - +/* Define the get system state macro. */ + #ifndef TX_THREAD_GET_SYSTEM_STATE #ifndef TX_MISRA_ENABLE + +#ifdef __CC_ARM /* ARM Compiler 5 */ + +register unsigned int _ipsr __asm("ipsr"); +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _ipsr) + +#elif defined(__GNUC__) /* GCC and ARM Compiler 6 */ + +__attribute__( ( always_inline ) ) static inline unsigned int __get_ipsr_value(void) +{ +unsigned int ipsr_value; + __asm__ volatile (" MRS %0,IPSR ": "=r" (ipsr_value) ); + return(ipsr_value); +} + +#define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_ipsr_value()) + +#elif defined(__ICCARM__) /* IAR */ + #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | __get_IPSR()) -#else + +#endif /* TX_THREAD_GET_SYSTEM_STATE for different compilers */ + +#else /* TX_MISRA_ENABLE is defined, use MISRA function. */ ULONG _tx_misra_ipsr_get(VOID); #define TX_THREAD_GET_SYSTEM_STATE() (_tx_thread_system_state | _tx_misra_ipsr_get()) -#endif -#endif +#endif /* TX_MISRA_ENABLE */ +#endif /* TX_THREAD_GET_SYSTEM_STATE */ /* Define the check for whether or not to call the _tx_thread_system_return function. A non-zero value @@ -427,92 +516,211 @@ ULONG _tx_misra_ipsr_get(VOID); zero after initialization for Cortex-M ports. */ #ifndef TX_THREAD_SYSTEM_RETURN_CHECK -#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); +#define TX_THREAD_SYSTEM_RETURN_CHECK(c) (c) = ((ULONG) _tx_thread_preempt_disable); #endif - -/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to +/* Define the macro to ensure _tx_thread_preempt_disable is set early in initialization in order to prevent early scheduling on Cortex-M parts. */ - + #define TX_PORT_SPECIFIC_POST_INITIALIZATION _tx_thread_preempt_disable++; -/* Determine if the ARM architecture has the CLZ instruction. This is available on - architectures v5 and above. If available, redefine the macro for calculating the - lowest bit set. */ + #ifndef TX_DISABLE_INLINE -#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT)__CLZ(__RBIT((m))); +/* Define the TX_LOWEST_SET_BIT_CALCULATE macro for each compiler. */ +#ifdef __ICCARM__ /* IAR Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __CLZ(__RBIT((m))); +#elif defined(__CC_ARM) /* AC5 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) (b) = (UINT) __clz(__rbit((m))); +#elif defined(__GNUC__) /* GCC and AC6 Compiler */ +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) __asm__ volatile (" RBIT %0,%1 ": "=r" (m) : "r" (m) ); \ + __asm__ volatile (" CLZ %0,%1 ": "=r" (b) : "r" (m) ); +#else +#error "Compiler not supported." +#endif + + + +/* Define the interrupt disable/restore macros for each compiler. */ + +#if defined(__GNUC__) || defined(__ICCARM__) + +/*** GCC/AC6 and IAR ***/ + +__attribute__( ( always_inline ) ) static inline UINT __get_interrupt_posture(void) +{ +UINT posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS %0, BASEPRI ": "=r" (posture)); +#else + __asm__ volatile ("MRS %0, PRIMASK ": "=r" (posture)); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +__attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) +{ + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); +} +#else +__attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) +{ + __asm__ volatile ("CPSIE i": : : "memory"); +} +#endif +__attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif +} +__attribute__( ( always_inline ) ) static inline UINT __disable_interrupts(void) +{ +UINT int_posture; -/* 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. */ + int_posture = __get_interrupt_posture(); -#ifdef TX_DISABLE_INLINE +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i" : : : "memory"); +#endif + return(int_posture); +} -UINT _tx_thread_interrupt_disable(VOID); -VOID _tx_thread_interrupt_restore(UINT previous_posture); +__attribute__( ( always_inline ) ) static inline void _tx_thread_system_return_inline(void) +{ +UINT interrupt_save; -#define TX_INTERRUPT_SAVE_AREA register UINT interrupt_save; + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} -#define TX_DISABLE interrupt_save = _tx_thread_interrupt_disable(); +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -#define TX_RESTORE _tx_thread_interrupt_restore(interrupt_save); +/*** End GCC/AC6 and IAR ***/ + +#elif defined(__CC_ARM) +/*** AC5 ***/ + +static __inline unsigned int __get_interrupt_posture(void) +{ +unsigned int posture; +#ifdef TX_PORT_USE_BASEPRI + __asm__ volatile ("MRS #posture, BASEPRI"); #else + __asm__ volatile ("MRS #posture, PRIMASK"); +#endif + return(posture); +} + +#ifdef TX_PORT_USE_BASEPRI +static __inline void __set_basepri_value(unsigned int basepri_value) +{ + __asm__ volatile ("MSR BASEPRI, #basepri_value"); +} +#endif -#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);}; +static __inline unsigned int __disable_interrupts(void) +{ +unsigned int int_posture; -#define _tx_thread_system_return _tx_thread_system_return_inline + int_posture = __get_interrupt_posture(); + +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(TX_PORT_BASEPRI); +#else + __asm__ volatile ("CPSID i"); +#endif + return(int_posture); +} + +static __inline void __restore_interrupt(unsigned int int_posture) +{ +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(int_posture); +#else + __asm__ volatile ("MSR PRIMASK, #int_posture"); +#endif +} static void _tx_thread_system_return_inline(void) { -__istate_t interrupt_save; +unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); - if (__get_IPSR() == 0) + if (_ipsr == 0) { - interrupt_save = __get_interrupt_state(); - __enable_interrupt(); - __set_interrupt_state(interrupt_save); +#ifdef TX_PORT_USE_BASEPRI + interrupt_save = __get_interrupt_posture(); + __set_basepri_value(0); + __set_basepri_value(interrupt_save); +#else + interrupt_save = __disable_irq(); + __enable_irq(); + if (interrupt_save != 0) + __disable_irq(); +#endif } } -#endif +#define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; +#define TX_DISABLE interrupt_save = __disable_interrupts(); +#define TX_RESTORE __restore_interrupt(interrupt_save); -/* Define FPU extension for the Cortex-M7. Each is assumed to be called in the context of the executing - thread. These are no longer needed, but are preserved for backward compatibility only. */ +/*** End AC5 ***/ -void tx_thread_fpu_enable(void); -void tx_thread_fpu_disable(void); +#endif /* Interrupt disable/restore macros for each compiler. */ +/* Redefine _tx_thread_system_return for improved performance. */ +#define _tx_thread_system_return _tx_thread_system_return_inline -/* Define the interrupt lockout macros for each ThreadX object. */ +#else /* TX_DISABLE_INLINE is defined */ -#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 +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); +#endif /* TX_DISABLE_INLINE */ + + +/* Define FPU extension for the Cortex-M. Each is assumed to be called in the context of the executing + thread. These are no longer needed, but are preserved for backward compatibility only. */ + +void tx_thread_fpu_enable(void); +void tx_thread_fpu_disable(void); /* 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 Cortex-M7/IAR Version 6.1.10 *"; +CHAR _tx_version_id[] = + "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX Cortex-M7 Version 6.2.0 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; @@ -521,5 +729,4 @@ extern CHAR _tx_version_id[]; #endif #endif - #endif diff --git a/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s b/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s index 53c60fbcd..ab3fef693 100644 --- a/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s +++ b/ports_module/cortex_m7/iar/module_manager/src/tx_misra.s @@ -102,12 +102,22 @@ PUBLIC _tx_misra_fpccr_get PUBLIC _tx_misra_vfp_touch #endif - PUBLIC _tx_version_id + PUBLIC _tx_misra_event_flags_group_not_used + PUBLIC _tx_misra_event_flags_set_notify_not_used + PUBLIC _tx_misra_queue_not_used + PUBLIC _tx_misra_queue_send_notify_not_used + PUBLIC _tx_misra_semaphore_not_used + PUBLIC _tx_misra_semaphore_put_notify_not_used + PUBLIC _tx_misra_thread_entry_exit_notify_not_used + PUBLIC _tx_misra_thread_not_used + +#ifdef TX_MISRA_ENABLE + PUBLIC _tx_version_id SECTION `.data`:DATA:REORDER:NOROOT(2) DATA -// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; +// 51 CHAR _tx_version_id[100] = "Copyright (c) Microsoft Corporation. All rights reserved. * ThreadX 6.1 MISRA C Compliant *"; _tx_version_id: DC8 43H, 6FH, 70H, 79H, 72H, 69H, 67H, 68H DC8 74H, 20H, 28H, 63H, 29H, 20H, 31H, 39H @@ -115,11 +125,12 @@ _tx_version_id: DC8 45H, 78H, 70H, 72H, 65H, 73H, 73H, 20H DC8 4CH, 6FH, 67H, 69H, 63H, 20H, 49H, 6EH DC8 63H, 2EH, 20H, 2AH, 20H, 54H, 68H, 72H - DC8 65H, 61H, 64H, 58H, 20H, 35H, 2EH, 38H + DC8 65H, 61H, 64H, 58H, 20H, 36H, 2EH, 31H DC8 20H, 4DH, 49H, 53H, 52H, 41H, 20H, 43H DC8 20H, 43H, 6FH, 6DH, 70H, 6CH, 69H, 61H DC8 6EH, 74H, 20H, 2AH, 0 DC8 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#endif //TX_MISRA_ENABLE /**************************************************************************/ /**************************************************************************/ @@ -139,7 +150,7 @@ _tx_misra_memset: MOVS R1,R0 MOVS R0,R4 BL __aeabi_memset - POP {R4,PC} ;; return + POP {R4,PC} // return /**************************************************************************/ /**************************************************************************/ @@ -153,7 +164,7 @@ _tx_misra_memset: THUMB _tx_misra_uchar_pointer_add: ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -169,7 +180,7 @@ _tx_misra_uchar_pointer_add: _tx_misra_uchar_pointer_sub: RSBS R1,R1,#+0 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -184,21 +195,97 @@ _tx_misra_uchar_pointer_sub: THUMB _tx_misra_uchar_pointer_dif: SUBS R0,R0,R1 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - + BX LR // return + + +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ +/** */ +/** This single function serves all of the below prototypes. */ +/** */ +/** ULONG _tx_misra_pointer_to_ulong_convert(VOID *ptr); */ +/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ +/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ +/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ +/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ +/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ +/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ +/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ +/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ +/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ +/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ +/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ +/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ +/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ +/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ +/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ +/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ +/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ +/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ +/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ +/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ +/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ +/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ +/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ +/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ +/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ +/** VOID _tx_misra_event_flags_group_not_used(TX_EVENT_FLAGS_GROUP *group_ptr); */ +/** VOID _tx_misra_event_flags_set_notify_not_used(VOID (*events_set_notify)(TX_EVENT_FLAGS_GROUP *notify_group_ptr)); */ +/** VOID _tx_misra_queue_not_used(TX_QUEUE *queue_ptr); */ +/** VOID _tx_misra_queue_send_notify_not_used(VOID (*queue_send_notify)(TX_QUEUE *notify_queue_ptr)); */ +/** VOID _tx_misra_semaphore_not_used(TX_SEMAPHORE *semaphore_ptr); */ +/** VOID _tx_misra_semaphore_put_notify_not_used(VOID (*semaphore_put_notify)(TX_SEMAPHORE *notify_semaphore_ptr)); */ +/** VOID _tx_misra_thread_not_used(TX_THREAD *thread_ptr); */ +/** VOID _tx_misra_thread_entry_exit_notify_not_used(VOID (*thread_entry_exit_notify)(TX_THREAD *notify_thread_ptr, UINT id)); */ +/** */ +/************************************************************************************************************************************/ +/************************************************************************************************************************************/ SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_pointer_to_ulong_convert: - BX LR ;; return +_tx_misra_ulong_to_pointer_convert: +_tx_misra_indirect_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_indirect_uchar_pointer_convert: +_tx_misra_block_pool_to_uchar_pointer_convert: +_tx_misra_void_to_block_pool_pointer_convert: +_tx_misra_void_to_uchar_pointer_convert: +_tx_misra_uchar_to_block_pool_pointer_convert: +_tx_misra_void_to_indirect_uchar_pointer_convert: +_tx_misra_void_to_byte_pool_pointer_convert: +_tx_misra_byte_pool_to_uchar_pointer_convert: +_tx_misra_uchar_to_align_type_pointer_convert: +_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: +_tx_misra_void_to_event_flags_pointer_convert: +_tx_misra_void_to_ulong_pointer_convert: +_tx_misra_void_to_mutex_pointer_convert: +_tx_misra_void_to_queue_pointer_convert: +_tx_misra_void_to_semaphore_pointer_convert: +_tx_misra_uchar_to_void_pointer_convert: +_tx_misra_ulong_to_thread_pointer_convert: +_tx_misra_timer_indirect_to_void_pointer_convert: +_tx_misra_const_char_to_char_pointer_convert: +_tx_misra_void_to_thread_pointer_convert: +#ifdef TX_ENABLE_EVENT_TRACE +_tx_misra_object_to_uchar_pointer_convert: +_tx_misra_uchar_to_object_pointer_convert: +_tx_misra_uchar_to_header_pointer_convert: +_tx_misra_uchar_to_entry_pointer_convert: +_tx_misra_entry_to_uchar_pointer_convert: +#endif +_tx_misra_char_to_uchar_pointer_convert: +_tx_misra_event_flags_group_not_used: +_tx_misra_event_flags_set_notify_not_used: +_tx_misra_queue_not_used: +_tx_misra_queue_send_notify_not_used: +_tx_misra_semaphore_not_used: +_tx_misra_semaphore_put_notify_not_used: +_tx_misra_thread_entry_exit_notify_not_used: +_tx_misra_thread_not_used: + + BX LR // return /**************************************************************************/ @@ -213,7 +300,7 @@ _tx_misra_pointer_to_ulong_convert: THUMB _tx_misra_ulong_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -230,7 +317,7 @@ _tx_misra_ulong_pointer_sub: MVNS R2,#+3 MULS R1,R2,R1 ADD R0,R0,R1 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -246,21 +333,7 @@ _tx_misra_ulong_pointer_sub: _tx_misra_ulong_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_ulong_to_pointer_convert(ULONG input); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -299,7 +372,7 @@ _tx_misra_message_copy: STR R3,[R0, #+0] STR R4,[R1, #+0] POP {R4,R5} - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -316,7 +389,7 @@ _tx_misra_message_copy: _tx_misra_timer_pointer_dif: SUBS R0,R0,R1 ASRS R0,R0,#+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -332,7 +405,7 @@ _tx_misra_timer_pointer_dif: THUMB _tx_misra_timer_pointer_add: ADD R0,R0,R1, LSL #+2 - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -347,12 +420,9 @@ _tx_misra_timer_pointer_add: SECTION `.text`:CODE:NOROOT(1) THUMB _tx_misra_user_timer_pointer_get: - ADDS R2,R0,#+8 - SUBS R2,R2,R0 - RSBS R2,R2,#+0 - ADD R0,R0,R2 - STR R0,[R1, #+0] - BX LR ;; return + SUBS R0,#8 + STR R0,[R1, #+0] + BX LR // return /**************************************************************************/ @@ -374,7 +444,7 @@ _tx_misra_thread_stack_check: CMP R4,#+0 BEQ.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+0] - LDR.N R2,??DataTable2 ;; 0x54485244 + LDR.N R2,??DataTable2 // 0x54485244 CMP R1,R2 BNE.N ??_tx_misra_thread_stack_check_0 LDR R1,[R4, #+8] @@ -412,7 +482,7 @@ _tx_misra_thread_stack_check: BL _tx_thread_interrupt_disable ??_tx_misra_thread_stack_check_0: BL _tx_thread_interrupt_restore - POP {R0,R4,R5,PC} ;; return + POP {R0,R4,R5,PC} // return #ifdef TX_ENABLE_EVENT_TRACE @@ -500,7 +570,7 @@ _tx_misra_trace_event_insert: LDR R0,[R0, #+0] STR R4,[R0, #+32] ??_tx_misra_trace_event_insert_0: - POP {R0,R4-R7,PC} ;; return + POP {R0,R4-R7,PC} // return SECTION `.text`:CODE:NOROOT(2) @@ -552,7 +622,7 @@ _tx_misra_trace_event_insert: THUMB _tx_misra_time_stamp_get: MOVS R0,#+0 - BX LR ;; return + BX LR // return #endif @@ -587,203 +657,7 @@ _tx_misra_time_stamp_get: THUMB _tx_misra_always_true: MOVS R0,#+1 - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_indirect_void_to_uchar_pointer_convert(VOID **return_ptr); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_indirect_void_to_uchar_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_uchar_to_indirect_uchar_pointer_convert(UCHAR *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/***********************************************************************************/ -/***********************************************************************************/ -/** */ -/** UCHAR *_tx_misra_block_pool_to_uchar_pointer_convert(TX_BLOCK_POOL *pool); */ -/** */ -/***********************************************************************************/ -/***********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_block_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_void_to_block_pool_pointer_convert(VOID *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_block_pool_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** UCHAR *_tx_misra_void_to_uchar_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************/ -/************************************************************************************/ -/** */ -/** TX_BLOCK_POOL *_tx_misra_uchar_to_block_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************/ -/************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_block_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************/ -/**************************************************************************************/ -/** */ -/** UCHAR **_tx_misra_void_to_indirect_uchar_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************/ -/**************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_indirect_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** TX_BYTE_POOL *_tx_misra_void_to_byte_pool_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_byte_pool_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_byte_pool_to_uchar_pointer_convert(TX_BYTE_POOL *pool); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_byte_pool_to_uchar_pointer_convert: - BX LR ;; return - - -/*****************************************************************************************/ -/*****************************************************************************************/ -/** */ -/** ALIGN_TYPE *_tx_misra_uchar_to_align_type_pointer_convert(UCHAR *pointer); */ -/** */ -/*****************************************************************************************/ -/*****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_align_type_pointer_convert: - BX LR ;; return - - -/****************************************************************************************************/ -/****************************************************************************************************/ -/** */ -/** TX_BYTE_POOL **_tx_misra_uchar_to_indirect_byte_pool_pointer_convert(UCHAR *pointer); */ -/** */ -/****************************************************************************************************/ -/****************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_indirect_byte_pool_pointer_convert: - BX LR ;; return - - -/**************************************************************************************************/ -/**************************************************************************************************/ -/** */ -/** TX_EVENT_FLAGS_GROUP *_tx_misra_void_to_event_flags_pointer_convert(VOID *pointer); */ -/** */ -/**************************************************************************************************/ -/**************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_event_flags_pointer_convert: - BX LR ;; return - - -/*****************************************************************************/ -/*****************************************************************************/ -/** */ -/** ULONG *_tx_misra_void_to_ulong_pointer_convert(VOID *pointer); */ -/** */ -/*****************************************************************************/ -/*****************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_ulong_pointer_convert: - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_MUTEX *_tx_misra_void_to_mutex_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_mutex_pointer_convert: - BX LR ;; return + BX LR // return /**************************************************************************/ @@ -798,192 +672,7 @@ _tx_misra_void_to_mutex_pointer_convert: THUMB _tx_misra_status_get: MOVS R0,#+0 - BX LR ;; return - - -/********************************************************************************/ -/********************************************************************************/ -/** */ -/** TX_QUEUE *_tx_misra_void_to_queue_pointer_convert(VOID *pointer); */ -/** */ -/********************************************************************************/ -/********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_queue_pointer_convert: - BX LR ;; return - - -/****************************************************************************************/ -/****************************************************************************************/ -/** */ -/** TX_SEMAPHORE *_tx_misra_void_to_semaphore_pointer_convert(VOID *pointer); */ -/** */ -/****************************************************************************************/ -/****************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_semaphore_pointer_convert: - BX LR ;; return - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** VOID *_tx_misra_uchar_to_void_pointer_convert(UCHAR *pointer); */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_void_pointer_convert: - BX LR ;; return - - -/*********************************************************************************/ -/*********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_ulong_to_thread_pointer_convert(ULONG value); */ -/** */ -/*********************************************************************************/ -/*********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_ulong_to_thread_pointer_convert: - BX LR ;; return - - -/***************************************************************************************************/ -/***************************************************************************************************/ -/** */ -/** VOID *_tx_misra_timer_indirect_to_void_pointer_convert(TX_TIMER_INTERNAL **pointer); */ -/** */ -/***************************************************************************************************/ -/***************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_timer_indirect_to_void_pointer_convert: - BX LR ;; return - - -/***************************************************************************************/ -/***************************************************************************************/ -/** */ -/** CHAR *_tx_misra_const_char_to_char_pointer_convert(const char *pointer); */ -/** */ -/***************************************************************************************/ -/***************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_const_char_to_char_pointer_convert: - BX LR ;; return - - -/**********************************************************************************/ -/**********************************************************************************/ -/** */ -/** TX_THREAD *_tx_misra_void_to_thread_pointer_convert(void *pointer); */ -/** */ -/**********************************************************************************/ -/**********************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_void_to_thread_pointer_convert: - BX LR ;; return - - -#ifdef TX_ENABLE_EVENT_TRACE - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_object_to_uchar_pointer_convert(TX_TRACE_OBJECT_ENTRY *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_object_to_uchar_pointer_convert: - BX LR ;; return - - -/************************************************************************************************/ -/************************************************************************************************/ -/** */ -/** TX_TRACE_OBJECT_ENTRY *_tx_misra_uchar_to_object_pointer_convert(UCHAR *pointer); */ -/** */ -/************************************************************************************************/ -/************************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_object_pointer_convert: - BX LR ;; return - - -/******************************************************************************************/ -/******************************************************************************************/ -/** */ -/** TX_TRACE_HEADER *_tx_misra_uchar_to_header_pointer_convert(UCHAR *pointer); */ -/** */ -/******************************************************************************************/ -/******************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_header_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** TX_TRACE_BUFFER_ENTRY *_tx_misra_uchar_to_entry_pointer_convert(UCHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_uchar_to_entry_pointer_convert: - BX LR ;; return - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_entry_to_uchar_pointer_convert(TX_TRACE_BUFFER_ENTRY *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_entry_to_uchar_pointer_convert: - BX LR ;; return -#endif - - -/***********************************************************************************************/ -/***********************************************************************************************/ -/** */ -/** UCHAR *_tx_misra_char_to_uchar_pointer_convert(CHAR *pointer); */ -/** */ -/***********************************************************************************************/ -/***********************************************************************************************/ - - SECTION `.text`:CODE:NOROOT(1) - THUMB -_tx_misra_char_to_uchar_pointer_convert: - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -998,7 +687,7 @@ _tx_misra_char_to_uchar_pointer_convert: THUMB _tx_misra_ipsr_get: MRS R0, IPSR - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1013,7 +702,7 @@ _tx_misra_ipsr_get: THUMB _tx_misra_control_get: MRS R0, CONTROL - BX LR ;; return + BX LR // return /***********************************************************************************************/ @@ -1028,7 +717,7 @@ _tx_misra_control_get: THUMB _tx_misra_control_set: MSR CONTROL, R0 - BX LR ;; return + BX LR // return #ifdef __ARMVFP__ @@ -1044,9 +733,9 @@ _tx_misra_control_set: SECTION `.text`:CODE:NOROOT(2) THUMB _tx_misra_fpccr_get: - LDR r0, =0xE000EF34 ; Build FPCCR address - LDR r0, [r0] ; Load FPCCR value - BX LR ;; return + LDR r0, =0xE000EF34 // Build FPCCR address + LDR r0, [r0] // Load FPCCR value + BX LR // return /***********************************************************************************************/ @@ -1061,7 +750,7 @@ _tx_misra_fpccr_get: THUMB _tx_misra_vfp_touch: vmov.f32 s0, s0 - BX LR ;; return + BX LR // return #endif diff --git a/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s index 632b507c6..4e0ab5440 100644 --- a/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_module/cortex_m7/iar/module_manager/src/tx_thread_schedule.s @@ -37,7 +37,7 @@ /* FUNCTION RELEASE */ /* */ /* _tx_thread_schedule Cortex-M7/IAR */ -/* 6.1.12 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* Scott Larson, Microsoft Corporation */ @@ -77,6 +77,8 @@ /* MPU reloading, optional */ /* default MPU settings, */ /* resulting in version 6.1.12 */ +/* 10-31-2022 Scott Larson Added low power support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ // VOID _tx_thread_schedule(VOID) @@ -325,11 +327,25 @@ __tx_ts_wait: #endif LDR r1, [r2] // Pickup the next thread to execute pointer CBNZ r1, __tx_ts_ready // If non-NULL, a new thread is ready! + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_enter // Possibly enter low power mode + POP {r0-r3} +#endif + #ifdef TX_ENABLE_WFI DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed #endif + +#ifdef TX_LOW_POWER + PUSH {r0-r3} + BL tx_low_power_exit // Exit low power mode + POP {r0-r3} +#endif + #ifdef TX_PORT_USE_BASEPRI MOV r4, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r4 diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.cproject b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.cproject new file mode 100644 index 000000000..cb9aa7c85 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.cproject @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.project b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.project new file mode 100644 index 000000000..29c218ae8 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/.project @@ -0,0 +1,27 @@ + + + demo_threadx + + + cortex-r8_tx + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.S b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.S new file mode 100644 index 000000000..eb1f366e8 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.S @@ -0,0 +1,292 @@ +; ------------------------------------------------------------ +; Cortex-R MPCore - Interrupt Controller functions +; +; Copyright ARM Ltd 2009. All rights reserved. +; ------------------------------------------------------------ + + PRESERVE8 + + AREA MP_GIC, CODE, READONLY + +; ------------------------------------------------------------ +; GIC +; ------------------------------------------------------------ + + ; CPU Interface offset from base of private peripheral space --> 0x0100 + ; Interrupt Distributor offset from base of private peripheral space --> 0x1000 + + ; Typical calls to enable interrupt ID X: + ; enable_irq_id(X) <-- Enable that ID + ; set_irq_priority(X, 0) <-- Set the priority of X to 0 (the max priority) + ; set_priority_mask(0x1F) <-- Set CPU's priority mask to 0x1F (the lowest priority) + ; enable_GIC() <-- Enable the GIC (global) + ; enable_gic_processor_interface() <-- Enable the CPU interface (local to the CPU) + + + EXPORT enable_GIC + ; void enable_GIC(void) + ; Global enable of the Interrupt Distributor +enable_GIC PROC + + ; Get base address of private perpherial space + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + ADD r0, r0, #0x1000 ; Add the GIC offset + + LDR r1, [r0] ; Read the GIC's Enable Register (ICDDCR) + ORR r1, r1, #0x01 ; Set bit 0, the enable bit + STR r1, [r0] ; Write the GIC's Enable Register (ICDDCR) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT disable_GIC + ; void disable_GIC(void) + ; Global disable of the Interrupt Distributor +disable_GIC PROC + + ; Get base address of private perpherial space + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + ADD r0, r0, #0x1000 ; Add the GIC offset + + LDR r1, [r0] ; Read the GIC's Enable Register (ICDDCR) + BIC r1, r1, #0x01 ; Set bit 0, the enable bit + STR r1, [r0] ; Write the GIC's Enable Register (ICDDCR) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT enable_irq_id + ; void enable_irq_id(unsigned int ID) + ; Enables the interrupt source number ID +enable_irq_id PROC + + ; Get base address of private perpherial space + MOV r1, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; Each interrupt source has an enable bit in the GIC. These + ; are grouped into registers, with 32 sources per register + ; First, we need to identify which 32 bit block the interrupt lives in + MOV r2, r1 ; Make working copy of ID in r2 + MOV r2, r2, LSR #5 ; LSR by 5 places, affective divide by 32 + ; r2 now contains the 32 bit block this ID lives in + MOV r2, r2, LSL #2 ; Now multiply by 4, to covert offset into an address offset (four bytes per reg) + + ; Now work out which bit within the 32 bit block the ID is + AND r1, r1, #0x1F ; Mask off to give offset within 32bit block + MOV r3, #1 ; Move enable value into r3 + MOV r3, r3, LSL r1 ; Shift it left to position of ID + + ADD r2, r2, #0x1100 ; Add the base offset of the Enable Set registers to the offset for the ID + STR r3, [r0, r2] ; Store out (ICDISER) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT disable_irq_id + ; void disable_irq_id(unsigned int ID) + ; Disables the interrupt source number ID +disable_irq_id PROC + + ; Get base address of private perpherial space + MOV r1, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; First, we need to identify which 32 bit block the interrupt lives in + MOV r2, r1 ; Make working copy of ID in r2 + MOV r2, r2, LSR #5 ; LSR by 5 places, affective divide by 32 + ; r2 now contains the 32 bit block this ID lives in + MOV r2, r2, LSL #2 ; Now multiply by 4, to covert offset into an address offset (four bytes per reg) + + ; Now work out which bit within the 32 bit block the ID is + AND r1, r1, #0x1F ; Mask off to give offset within 32bit block + MOV r3, #1 ; Move enable value into r3 + MOV r3, r3, LSL r1 ; Shift it left to position of ID in 32 bit block + + ADD r2, r2, #0x1180 ; Add the base offset of the Enable Clear registers to the offset for the ID + STR r3, [r0, r2] ; Store out (ICDICER) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT set_irq_priority + ; void set_irq_priority(unsigned int ID, unsigned int priority) + ; Sets the priority of the specifed ID + ; r0 = ID + ; r1 = priority +set_irq_priority PROC + + ; Get base address of private perpherial space + MOV r2, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; r0 = base addr + ; r1 = priority + ; r2 = ID + + ; Make sure that priority value is only 5 bits, and convert to expected format + AND r1, r1, #0x1F + MOV r1, r1, LSL #3 + + ; Find which priority register this ID lives in + BIC r3, r2, #0x03 ; Make a copy of the ID, clearing off the bottom two bits + ; There are four IDs per reg, by clearing the bottom two bits we get an address offset + ADD r3, r3, #0x1400 ; Now add the offset of the Priority Level registers from the base of the private peripheral space + ADD r0, r0, r3 ; Now add in the base address of the private peripheral space, giving us the absolute address + + + ; Now work out which ID in the register it is + AND r2, r2, #0x03 ; Clear all but the bottom four bits, leaves which ID in the reg it is (which byte) + MOV r2, r2, LSL #3 ; Multiply by 8, this gives a bit offset + + ; Read -> Modify -> Write + MOV r12, #0xFF ; Mask (8 bits) + MOV r12, r12, LSL r2 ; Move mask into correct bit position + MOV r1, r1, LSL r2 ; Also, move passed in priority value into correct bit position + + LDR r3, [r0] ; Read current value of the Priority Level register (ICDIPR) + BIC r3, r3, r12 ; Clear appropiate field + ORR r3, r3, r1 ; Now OR in the priority value + STR r3, [r0] ; And store it back again (ICDIPR) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT enable_gic_processor_interface + ; void enable_gic_processor_interface(void) + ; Enables the processor interface + ; Must been done one each CPU seperately +enable_gic_processor_interface PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x100] ; Read the Processor Interface Control register (ICCICR/ICPICR) + ORR r1, r1, #0x03 ; Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts + STR r1, [r0, #0x100] ; Write the Processor Interface Control register (ICCICR/ICPICR) + + BX lr + ENDP + + +; ------------------------------------------------------------ + + EXPORT disable_gic_processor_interface + ; void disable_gic_processor_interface(void) + ; Disables the processor interface + ; Must been done one each CPU seperately +disable_gic_processor_interface PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x100] ; Read the Processor Interface Control register (ICCICR/ICPICR) + BIC r1, r1, #0x03 ; Bit 0: Enables secure interrupts, Bit 1: Enables Non-Secure interrupts + STR r1, [r0, #0x100] ; Write the Processor Interface Control register (ICCICR/ICPICR) + + BX lr + ENDP + + +; ------------------------------------------------------------ + + EXPORT set_priority_mask + ; void set_priority_mask(unsigned int priority) + ; Sets the Priority mask register for the CPU run on + ; The reset value masks ALL interrupts! +set_priority_mask PROC + + ; Get base address of private perpherial space + MOV r1, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + STR r1, [r0, #0x0104] ; Write the Priority Mask register (ICCPMR/ICCIPMR) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT set_binary_port + ; void set_binary_port(unsigned int priority) + ; Sets the Binary Point Register for the CPU run on +set_binary_port PROC + + ; Get base address of private perpherial space + MOV r1, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + STR r1, [r0, #0x0108] ; Write the Binary register (ICCBPR/ICCBPR) + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT read_irq_ack + ; unsigned int read_irq_ack(void) + ; Returns the value of the Interrupt Acknowledge Register +read_irq_ack PROC + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + LDR r0, [r0, #0x010C] ; Read the Interrupt Acknowledge Register (ICCIAR) + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT write_end_of_irq + ; void write_end_of_irq(unsigned int ID) + ; Writes ID to the End Of Interrupt register +write_end_of_irq PROC + + ; Get base address of private perpherial space + MOV r1, r0 ; Back up passed in ID value + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + STR r1, [r0, #0x0110] ; Write ID to the End of Interrupt register (ICCEOIR) + + BX lr + ENDP + +; ------------------------------------------------------------ +; SGI +; ------------------------------------------------------------ + + EXPORT send_sgi + ; void send_sgi(unsigned int ID, unsigned int target_list, unsigned int filter_list); + ; Send a software generate interrupt +send_sgi PROC + + AND r3, r0, #0x0F ; Mask off unused bits of ID, and move to r3 + AND r1, r1, #0x0F ; Mask off unused bits of target_filter + AND r2, r2, #0x0F ; Mask off unused bits of filter_list + + ORR r3, r3, r1, LSL #16 ; Combine ID and target_filter + ORR r3, r3, r2, LSL #24 ; and now the filter list + + ; Get the address of the GIC + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + ADD r0, r0, #0x1F00 ; Add offset of the sgi_trigger reg + + STR r3, [r0] ; Write to the Software Generated Interrupt Register (ICDSGIR) + + BX lr + ENDP + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of MP_GIC.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.h new file mode 100644 index 000000000..81551bee5 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GIC.h @@ -0,0 +1,80 @@ +// ------------------------------------------------------------ +// Cortex-R MPCore - Interrupt Controller functions +// Header File +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _CORTEXA_GIC_ +#define _CORTEXA_GIC_ + +// ------------------------------------------------------------ +// GIC +// ------------------------------------------------------------ + +// Typical calls to enable interrupt ID X: +// enable_irq_id(X) <-- Enable that ID +// set_irq_priority(X, 0) <-- Set the priority of X to 0 (the max priority) +// set_priority_mask(0x1F) <-- Set Core's priority mask to 0x1F (the lowest priority) +// enable_GIC() <-- Enable the GIC (global) +// enable_gic_processor_interface() <-- Enable the CPU interface (local to the core) +// +// OR +// +// Use init_GIC() which is a simple switch everything on function! :-) +// + +// Global enable of the Interrupt Distributor +void enable_GIC(void); + +// Global disable of the Interrupt Distributor +void disable_GIC(void); + +// Enables the interrupt source number ID +void enable_irq_id(unsigned int ID); + +// Disables the interrupt source number ID +void disable_irq_id(unsigned int ID); + +// Sets the priority of the specifed ID +void set_irq_priority(unsigned int ID, unsigned int priority); + +// Enables the processor interface +// Must been done one each core seperately +void enable_gic_processor_interface(void); + +// Disables the processor interface +void disable_gic_processor_interface(void); + +// Sets the Priority mask register for the core run on +// The reset value masks ALL interrupts! +void set_priority_mask(unsigned int priority); + +// Sets the Binary Point Register for the core run on +void set_binary_port(unsigned int priority); + +// Returns the value of the Interrupt Acknowledge Register +unsigned int read_irq_ack(void); + +// Writes ID to the End Of Interrupt register +void write_end_of_irq(unsigned int ID); + +// Lazy Init function, a quick way of enabling interrupts +// * Enables the GIC (global) and CPU Interface (just for this core) +// * Enables interrupt sources 0->31, and sets their priority to 0x0 +// * Sets the CPU's Priority mask to 0x1F +// * Clears the CPSR I bit +void init_GIC(void); + +// ------------------------------------------------------------ +// SGI +// ------------------------------------------------------------ + +// Send a software generate interrupt +void send_sgi(unsigned int ID, unsigned int core_list, unsigned int filter_list); + +#endif + +// ------------------------------------------------------------ +// End of MP_GIC.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.h new file mode 100644 index 000000000..7a272b3ee --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.h @@ -0,0 +1,42 @@ +// ------------------------------------------------------------ +// Cortex-R MPCore - Global timer functions +// Header Filer +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _CORTEXA_GLOBAL_TIMER_ +#define _CORTEXA_GLOBAL_TIMER_ + +// Typical set of calls to enable Timer: +// init_global_timer( AUTO_INCREMENT>, INCREMENT_VALUE ); +// set_global_timer_comparator( UPPER_32_BITS, LOWER_32_BITS ); +// start_global_timer(); + + +// Sets up the private timer +// r0: IF 0 (AutoIncrement) ELSE (SingleShot) +// r1: Increment value (ignored if auto_increment != 0) +void init_global_timer(unsigned int auto_increment, unsigned int increment_value) + +// Sets the comparator value for this CPU +void set_global_timer_comparator(unsigned int top, unsigned int bottom); + +// Starts the private timer +void start_global_timer(void); + +// Stops the private timer +void stop_global_timer(void); + +// Reads the current value of the timer count register +// Returns bits 63:32 in *top, and bits 31:0 in *bottom +void read_global_timer(unsigned int* top, unsigned int* bottom); + +// Clears the private timer interrupt +void clear_global_timer_irq(void); + +#endif + +// ------------------------------------------------------------ +// End of MP_PrivateTimer.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.s b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.s new file mode 100644 index 000000000..042455877 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_GlobalTimer.s @@ -0,0 +1,169 @@ +; ------------------------------------------------------------ +; Cortex-R MPCore - Global timer functions +; +; Copyright ARM Ltd 2009. All rights reserved. +; ------------------------------------------------------------ + + PRESERVE8 + + AREA MP_PrivateTimer, CODE, READONLY + + ; PPI ID 27 + + + ; Typical set of calls to enable Timer: + ; init_global_timer() + ; set_global_timer_comparator() + ; start_global_timer() + +; ------------------------------------------------------------ + + EXPORT init_global_timer + ; void init_global_timer(unsigned int auto_increment, unsigned int increment_value) + ; Initializes the Global Timer, but does NOT set the enable bit + ; r0: IF 0 (AutoIncrement) ELSE (SingleShot) + ; r1: increment value +init_global_timer PROC + + ; Get base address of private perpherial space + MRC p15, 4, r2, c15, c0, 0 ; Read periph base address + + ; Control register bit layout + ; Bit 0 - Timer enable + ; Bit 1 - Comp enable + ; Bit 2 - IRQ enable + ; Bit 3 - Auto-increment enable + + ; Ensure the timer is disabled + LDR r3, [r2, #0x208] ; Read control reg + BIC r3, r3, #0x01 ; Clear enable bit + STR r3, [r2, #0x208] ; Write control reg + + ; Form control reg value + CMP r0, #0 ; Check whether to enable auto-reload + MOVNE r0, #0x00 ; No auto-reload + MOVEQ r0, #0x04 ; With auto-reload + STR r0, [r2, #0x208] ; Store to control register + + ; Store increment value + STREQ r1, [r2, #0x218] + + ; Clear timer value + MOV r0, #0x0 + STR r0, [r2, #0x0] + STR r0, [r2, #0x4] + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT set_global_timer_comparator + ; void set_global_timer_comparator(unsigned int top, unsigned int bottom); + ; Writes the comparator registers, and enable the comparator bit in the control register + ; r0: 63:32 of the comparator value + ; r1: 31:0 of the comparator value +set_global_timer_comparator PROC + + MRC p15, 4, r2, c15, c0, 0 ; Read periph base address + + ; Disable comparator before updating register + LDR r1, [r2, #0x208] ; Read control reg + BIC r3, r3, #0x02 ; Clear comparator enable bit + STR r3, [r2, #0x208] ; Write modified value back + + ; Write the comparator registers + STR r1, [r2, #0x210] ; Write lower 32 bits + STR r0, [r2, #0x214] ; Write upper 32 bits + DMB + + ; Re-enable the comparator + ORR r3, r3, #0x02 ; Set comparator enable bit + STR r3, [r2, #0x208] ; Write modified value back + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT start_global_timer + ; void start_global_timer(void) + ; Starts the global timer +start_global_timer PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x208] ; Read control reg + ORR r1, r1, #0x01 ; Set enable bit + STR r1, [r0, #0x208] ; Write modified value back + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT stop_global_timer + ; void stop_private_timer(void) + ; Stops the private timer +;stop_private_timer PROC +stop_global_timer PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x208] ; Read control reg + BIC r1, r1, #0x01 ; Clear enable bit + STR r1, [r0, #0x208] ; Write modified value back + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT get_global_timer_count + ; void read_global_timer(unsigned int* top, unsigned int* bottom) + ; Reads the current value of the timer count register + ; r0: Address of unsigned int for bits 63:32 + ; r1: Address of unsigned int for bits 31:0 +get_global_timer_count PROC + +get_global_timer_count_loop + MRC p15, 4, r2, c15, c0, 0 ; Read periph base address + + LDR r12,[r2, #0x04] ; Read bits 63:32 + LDR r3, [r2, #0x00] ; Read bits 31:0 + LDR r2, [r2, #0x04] ; Re-read bits 63:32 + + CMP r2, r12 ; Have the top bits changed? + BNE get_global_timer_count_loop + + ; Store result out to pointers + STR r2, [r0] + STR r3, [r1] + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT clear_global_timer_irq + ; void clear_global_timer_irq(void) + ; Clears the global timer interrupt +clear_global_timer_irq PROC + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; Clear the interrupt by writing 0x1 to the Timer's Interrupt Status register + MOV r1, #1 + STR r1, [r0, #0x20C] + + BX lr + ENDP + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of MP_GlobalTimer.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.h new file mode 100644 index 000000000..2a613b7e6 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.h @@ -0,0 +1,42 @@ +// ------------------------------------------------------------ +// Cortex-R MPCore - Mutex +// Header File +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _CORTEXA_MUTEX_ +#define _CORTEXA_MUTEX_ + +// Struct +// 0xFF=unlocked 0x0 = Locked by CPU 0, +// 0x1 = Locked by CPU 1, +// 0x2 = Locked by CPU 2, +// 0x3 = Locked by CPU 3 +typedef struct +{ + unsigned int lock; +}mutex_t; + +// Places mutex into a known state +// r0 = address of mutex_t +void init_mutex(mutex_t* pMutex); + +// Blocking call, returns once successfully locked a mutex +// r0 = address of mutex_t +void lock_mutex(mutex_t* pMutex); + +// Releases (unlock) mutex. Fails if CPU not owner of mutex. +// returns 0x0 for success, and 0x1 for failure +// r0 = address of mutex_t +unsigned int unlock_mutex(mutex_t* pMutex); + +// Returns 0x0 if mutex unlocked, 0x1 is locked +// r0 = address of mutex_t +void is_mutex_locked(mutex_t* pMutex); + +#endif + +// ------------------------------------------------------------ +// End of MP_Mutexes.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.s b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.s new file mode 100644 index 000000000..3c20b253c --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_Mutexes.s @@ -0,0 +1,123 @@ +; ------------------------------------------------------------ +; Cortex-R MPCore - Mutex Code +; +; Copyright ARM Ltd 2009. All rights reserved. +; ------------------------------------------------------------ + + PRESERVE8 + + AREA MP_Mutexes, CODE, READONLY + + ;NOTES + ; struct mutex_t defined in A9MP_Mutexes.h + ; typedef struct mutex_t + ; { + ; unsigned int lock; <-- offset 0 + ; } + ; + ; lock: 0xFF=unlocked 0x0 = Locked by CPU 0, 0x1 = Locked by CPU 1, 0x2 = Locked by CPU 2, 0x3 = Locked by CPU 3 + ; + +UNLOCKED EQU 0xFF + +; ------------------------------------------------------------ + + EXPORT init_mutex + ; void init_mutex(mutex_t* pMutex) + ; Places mutex into a known state + ; r0 = address of mutex_t +init_mutex PROC + + MOV r1, #UNLOCKED ; Mark as unlocked + STR r1, [r0] + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT lock_mutex + ; void lock_mutex(mutex_t* pMutex) + ; Blocking call, returns once successfully locked a mutex + ; r0 = address of mutex_t +lock_mutex PROC + + ; Is mutex locked? + ; ----------------- + LDREX r1, [r0] ; Read lock field + CMP r1, #UNLOCKED ; Compare with "unlocked" + + WFENE ; If mutex is locked, go into standby + BNE lock_mutex ; On waking re-check the mutex + + ; Attempt to lock mutex + ; ----------------------- + MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register + AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field. + STREX r2, r1, [r0] ; Attempt to lock mutex, by write CPU's ID to lock field + CMP r2, #0x0 ; Check wether store completed successfully (0=succeeded) + BNE lock_mutex ; If store failed, go back to beginning and try again + + DMB + + BX lr ; Return as mutex is now locked by this cpu + ENDP + +; ------------------------------------------------------------ + + EXPORT unlock_mutex + ; unsigned int unlock_mutex(mutex_t* pMutex) + ; Releases mutex, returns 0x0 for success and 0x1 for failure + ; r0 = address of mutex_t +unlock_mutex PROC + + ; Does this CPU own the mutex? + ; ----------------------------- + MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register + AND r1, r1, #0x03 ; Mask off, leaving the CPU ID in r1 + LDR r2, [r0] ; Read the lock field of the mutex + CMP r1, r2 ; Compare ID of this CPU with the lock owner + MOVNE r0, #0x1 ; If ID doesn't match, return "fail" + BXNE lr + + + ; Unlock mutex + ; ------------- + DMB ; Ensure that accesses to shared resource have completed + + MOV r1, #UNLOCKED ; Write "unlocked" into lock field + STR r1, [r0] + + DMB ; To ensure update of the mutex occurs before other CPUs awake + + SEV ; Send event to other CPUs, wakes anyone waiting on a mutex (using WFE) + + MOV r0, #0x0 ; Return "success" + BX lr + + ENDP + +; ------------------------------------------------------------ + + EXPORT is_mutex_locked + ; void is_mutex_locked(mutex_t* pMutex) + ; Returns 0x0 if mutex unlocked, 0x1 is locked + ; r0 = address of mutex_t +is_mutex_locked PROC + LDR r0, [r0] + CMP r0, #UNLOCKED + MOVEQ r0, #0x0 + MOVNE r0, #0x1 + BX lr + ENDP + + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of MP_Mutexes.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.h new file mode 100644 index 000000000..cd0d37f84 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.h @@ -0,0 +1,36 @@ +// ------------------------------------------------------------ +// Cortex-R MPCore - Private timer functions +// Header Filer +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _CORTEXA_PRIVATE_TIMER_ +#define _CORTEXA_PRIVATE_TIMER_ + +// Typical set of calls to enable Timer: +// init_private_timer(0xXXXX, 0) <-- Counter down value of 0xXXXX, with auto-reload +// start_private_timer() + +// Sets up the private timer +// r0: initial load value +// r1: IF 0 (AutoReload) ELSE (SingleShot) +void init_private_timer(unsigned int load_value, unsigned int auto_reload); + +// Starts the private timer +void start_private_timer(void); + +// Stops the private timer +void stop_private_timer(void); + +// Reads the current value of the timer count register +unsigned int get_private_timer_count(void); + +// Clears the private timer interrupt +void clear_private_timer_irq(void); + +#endif + +// ------------------------------------------------------------ +// End of MP_PrivateTimer.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.s b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.s new file mode 100644 index 000000000..3be7249b1 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_PrivateTimer.s @@ -0,0 +1,121 @@ +; ------------------------------------------------------------ +; Cortex-R MPCore - Private timer functions +; +; Copyright ARM Ltd 2009. All rights reserved. +; ------------------------------------------------------------ + + PRESERVE8 + + AREA MP_PrivateTimer, CODE, READONLY + + ; PPI ID 29 + + + ; Typical set of calls to enable Timer: + ; init_private_timer(0xXXXX, 0) <-- Counter down value of 0xXXXX, with auto-reload + ; start_private_timer() + + ; Timer offset from base of private peripheral space --> 0x600 + +; ------------------------------------------------------------ + + EXPORT init_private_timer + ; void init_private_timer(unsigned int load_value, unsigned int auto_reload) + ; Sets up the private timer + ; r0: initial load value + ; r1: IF 0 (AutoReload) ELSE (SingleShot) +init_private_timer PROC + + ; Get base address of private perpherial space + MOV r2, r0 ; Make a copy of r0 before corrupting + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; Set the load value + STR r2, [r0, #0x600] + + ; Control register bit layout + ; Bit 0 - Enable + ; Bit 1 - Auto-Reload ; see DE681117 + ; Bit 2 - IRQ Generation + + ; Form control reg value + CMP r1, #0 ; Check whether to enable auto-reload + MOVNE r2, #0x04 ; No auto-reload + MOVEQ r2, #0x06 ; With auto-reload + + ; Store to control register + STR r2, [r0, #0x608] + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT start_private_timer + ; void start_private_timer(void) + ; Starts the private timer +start_private_timer PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x608] ; Read control reg + ORR r1, r1, #0x01 ; Set enable bit + STR r1, [r0, #0x608] ; Write modified value back + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT stop_private_timer + ; void stop_private_timer(void) + ; Stops the private timer +stop_private_timer PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x608] ; Read control reg + BIC r1, r1, #0x01 ; Clear enable bit + STR r1, [r0, #0x608] ; Write modified value back + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT get_private_timer_count + ; unsigned int read_private_timer(void) + ; Reads the current value of the timer count register +get_private_timer_count PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r0, [r0, #0x604] ; Read count register + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT clear_private_timer_irq + ; void clear_private_timer_irq(void) + ; Clears the private timer interrupt +clear_private_timer_irq PROC + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + ; Clear the interrupt by writing 0x1 to the Timer's Interrupt Status register + MOV r1, #1 + STR r1, [r0, #0x60C] + + BX lr + ENDP + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of MP_PrivateTimer.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.h new file mode 100644 index 000000000..c9fe4da6c --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.h @@ -0,0 +1,67 @@ +// ------------------------------------------------------------ +// Cortex-R MPCore - Snoop Control Unit +// Header File +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _CORTEXA_SCU_ +#define _CORTEXA_SCU_ + +// ------------------------------------------------------------ +// SCU +// ------------------------------------------------------------ + +// Returns the base address of the private peripheral memory space +unsigned int get_base_addr(void); + +// Returns the CPU ID (0 to 3) of the CPU executed on +unsigned int get_cpu_id(void); + +// Returns the number of cores in the A9 Cluster +// NOTE: +// returns 0 = 1 core +// 1 = 2 cores etc... +// This is the format of the register, decided to leave it unchanged. +unsigned int get_num_cpus(void); + +// Go to sleep, never returns +void go_to_sleep(void); + +// ------------------------------------------------------------ +// SCU +// ------------------------------------------------------------ + +// Enables the SCU +void enable_scu(void); + +// Set this core as participating in SMP +void join_smp(void); + +// Set this core as NOT participating in SMP +void leave_smp(void); + +// The return value is 1 bit per core: +// bit 0 - CPU 0 +// bit 1 - CPU 1 +// etc... +unsigned int get_cpus_in_smp(void); + + //Enable the broadcasting of cache & TLB maintenance operations +// When enabled AND in SMP, broadcast all "inner sharable" +// cache and TLM maintenance operations to other SMP cores +void enable_maintenance_broadcast(void); + +// Disable the broadcasting of cache & TLB maintenance operations +void disable_maintenance_broadcast(void); + +// cpu: 0x0=CPU 0 0x1=CPU 1 etc... +// This function invalidates the SCU copy of the tag rams +// for the specified core. +void secure_SCU_invalidate(unsigned int cpu, unsigned int ways); + +#endif + +// ------------------------------------------------------------ +// End of MP_SCU.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.s b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.s new file mode 100644 index 000000000..cfed344f0 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/MP_SCU.s @@ -0,0 +1,193 @@ +; ------------------------------------------------------------ +; Cortex-R MPCore - SCU functions +; +; Copyright ARM Ltd 2009. All rights reserved. +; ------------------------------------------------------------ + + PRESERVE8 + + AREA MP_SCU, CODE, READONLY + +; ------------------------------------------------------------ +; Misc +; ------------------------------------------------------------ + + EXPORT get_base_addr + ; unsigned int get_base_addr(void) + ; Returns the base address of the private peripheral memory space +get_base_addr PROC + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address (see DE593076) + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT get_cpu_id + ; unsigned int get_cpu_id(void) + ; Returns the CPU ID (0 to 3) of the CPU executed on +get_cpu_id PROC + MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register + AND r0, r0, #0x03 ; Mask off, leaving the CPU ID field + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT get_num_cpus + ; unsigned int get_num_cpus(void) + ; Returns the number of CPUs in the A9 Cluster +get_num_cpus PROC + + ; Get base address of private perpherial space + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r0, [r0, #0x004] ; Read SCU Configuration register + AND r0, r0, #0x3 ; Bits 1:0 gives the number of cores + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT go_to_sleep + ; void go_to_sleep(void) +go_to_sleep PROC + WFI ; Go into standby + B go_to_sleep ; Catch in case of rogue events + BX lr + ENDP + +; ------------------------------------------------------------ +; SCU +; ------------------------------------------------------------ + + ; SCU offset from base of private peripheral space --> 0x000 + + EXPORT enable_scu + ; void enable_scu(void) + ; Enables the SCU +enable_scu PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r1, [r0, #0x0] ; Read the SCU Control Register + ORR r1, r1, #0x1 ; Set bit 0 (The Enable bit) + STR r1, [r0, #0x0] ; Write back modifed value + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT join_smp + ; void join_smp(void) + ; Set this CPU as participating in SMP +join_smp PROC + + ; SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg + + MRC p15, 0, r0, c1, c0, 1 ; Read ACTLR + ORR r0, r0, #0x040 ; Set bit 6 + MCR p15, 0, r0, c1, c0, 1 ; Write ACTLR + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT leave_smp + ; void leave_smp(void) + ; Set this CPU as NOT participating in SMP +leave_smp PROC + + ; SMP status is controlled by bit 6 of the CP15 Aux Ctrl Reg + + MRC p15, 0, r0, c1, c0, 1 ; Read ACTLR + BIC r0, r0, #0x040 ; Clear bit 6 + MCR p15, 0, r0, c1, c0, 1 ; Write ACTLR + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT get_cpus_in_smp + ; unsigned int get_cpus_in_smp(void) + ; The return value is 1 bit per core: + ; bit 0 - CPU 0 + ; bit 1 - CPU 1 + ; etc... +get_cpus_in_smp PROC + + MRC p15, 4, r0, c15, c0, 0 ; Read periph base address + + LDR r0, [r0, #0x004] ; Read SCU Configuration register + MOV r0, r0, LSR #4 ; Bits 7:4 gives the cores in SMP mode, shift then mask + AND r0, r0, #0x0F + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT enable_maintenance_broadcast + ; void enable_maintenance_broadcast(void) + ; Enable the broadcasting of cache & TLB maintenance operations + ; When enabled AND in SMP, broadcast all "inner sharable" + ; cache and TLM maintenance operations to other SMP cores +enable_maintenance_broadcast PROC + MRC p15, 0, r0, c1, c0, 1 ; Read Aux Ctrl register + ORR r0, r0, #0x01 ; Set the FW bit (bit 0) + MCR p15, 0, r0, c1, c0, 1 ; Write Aux Ctrl register + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT disable_maintenance_broadcast + ; void disable_maintenance_broadcast(void) + ; Disable the broadcasting of cache & TLB maintenance operations +disable_maintenance_broadcast PROC + MRC p15, 0, r0, c1, c0, 1 ; Read Aux Ctrl register + BIC r0, r0, #0x01 ; Clear the FW bit (bit 0) + MCR p15, 0, r0, c1, c0, 1 ; Write Aux Ctrl register + + BX lr + ENDP + +; ------------------------------------------------------------ + + EXPORT secure_SCU_invalidate + ; void secure_SCU_invalidate(unsigned int cpu, unsigned int ways) + ; cpu: 0x0=CPU 0 0x1=CPU 1 etc... + ; This function invalidates the SCU copy of the tag rams + ; for the specified core. Typically only done at start-up. + ; Possible flow: + ; - Invalidate L1 caches + ; - Invalidate SCU copy of TAG RAMs + ; - Join SMP +secure_SCU_invalidate PROC + AND r0, r0, #0x03 ; Mask off unused bits of CPU ID + MOV r0, r0, LSL #2 ; Convert into bit offset (four bits per core) + + AND r1, r1, #0x0F ; Mask off unused bits of ways + MOV r1, r1, LSL r0 ; Shift ways into the correct CPU field + + MRC p15, 4, r2, c15, c0, 0 ; Read periph base address + + STR r1, [r2, #0x0C] ; Write to SCU Invalidate All in Secure State + + BX lr + + ENDP + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of MP_SCU.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.c b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.c new file mode 100644 index 000000000..70f1c840c --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.c @@ -0,0 +1,444 @@ +/* This is a small demo of the high-performance ThreadX kernel. It includes examples of eight + threads of different priorities, using a message queue, semaphore, mutex, event flags group, + byte pool, and block pool. */ + +#include "tx_api.h" + +#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_TIMER timer_0; +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; + + +/* 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); + + +#ifdef TX_ENABLE_EVENT_TRACE + +UCHAR event_buffer[65536]; + +#endif + + + +int main(void) +{ + + /* Enter ThreadX. */ + tx_kernel_enter(); + + return 0; +} + + +/* Define what the initial system looks like. */ + +void tx_application_define(void *first_unused_memory) +{ + +CHAR *pointer; + + +#ifdef TX_ENABLE_EVENT_TRACE + + tx_trace_enable(event_buffer, sizeof(event_buffer), 32); +#endif + + /* Create a byte memory pool from which to allocate the thread stacks. */ + tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE); + + /* Allocate the stack for thread 0. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create the main thread. */ + tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0, + pointer, DEMO_STACK_SIZE, + 1, 1, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 1. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 1 and 2. These threads pass information through a ThreadX + message queue. It is also interesting to note that these threads have a time + slice. */ + tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 2. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2, + pointer, DEMO_STACK_SIZE, + 16, 16, 4, TX_AUTO_START); + + /* Allocate the stack for thread 3. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 3 and 4. These threads compete for a ThreadX counting semaphore. + An interesting thing here is that both threads share the same instruction area. */ + tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 4. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 5. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create thread 5. This thread simply pends on an event flag which will be set + by thread_0. */ + tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5, + pointer, DEMO_STACK_SIZE, + 4, 4, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 6. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + /* Create threads 6 and 7. These threads compete for a ThreadX mutex. */ + tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the stack for thread 7. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT); + + tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7, + pointer, DEMO_STACK_SIZE, + 8, 8, TX_NO_TIME_SLICE, TX_AUTO_START); + + /* Allocate the message queue. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT); + + /* Create the message queue shared by threads 1 and 2. */ + tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG)); + + /* Create the semaphore used by threads 3 and 4. */ + tx_semaphore_create(&semaphore_0, "semaphore 0", 1); + + /* Create the event flags group used by threads 1 and 5. */ + tx_event_flags_create(&event_flags_0, "event flags 0"); + + /* Create the mutex used by thread 6 and 7 without priority inheritance. */ + tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT); + + /* Allocate the memory for a small block pool. */ + tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT); + + /* Create a block memory pool to allocate a message buffer from. */ + tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE); + + /* Allocate a block and release the block memory. */ + tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT); + + /* Release the block back to the pool. */ + tx_block_release(pointer); +} + + + +/* Define the test threads. */ + +void thread_0_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sits in while-forever-sleep loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_0_counter++; + + /* Sleep for 10 ticks. */ + tx_thread_sleep(10); + + /* Set event flag 0 to wakeup thread 5. */ + status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_1_entry(ULONG thread_input) +{ + +UINT status; + + + /* This thread simply sends messages to a queue shared by thread 2. */ + while(1) + { + + /* Increment the thread counter. */ + thread_1_counter++; + + /* Send message to queue 0. */ + status = tx_queue_send(&queue_0, &thread_1_messages_sent, TX_WAIT_FOREVER); + + /* Check completion status. */ + if (status != TX_SUCCESS) + break; + + /* Increment the message sent. */ + thread_1_messages_sent++; + } +} + + +void thread_2_entry(ULONG thread_input) +{ + +ULONG received_message; +UINT status; + + /* This thread retrieves messages placed on the queue by thread 1. */ + while(1) + { + + /* Increment the thread counter. */ + thread_2_counter++; + + /* Retrieve a message from the queue. */ + status = tx_queue_receive(&queue_0, &received_message, TX_WAIT_FOREVER); + + /* Check completion status and make sure the message is what we + expected. */ + if ((status != TX_SUCCESS) || (received_message != thread_2_messages_received)) + break; + + /* Otherwise, all is okay. Increment the received message count. */ + thread_2_messages_received++; + } +} + + +void thread_3_and_4_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 3 and thread 4. As the loop + below shows, these function compete for ownership of semaphore_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 3) + thread_3_counter++; + else + thread_4_counter++; + + /* Get the semaphore with suspension. */ + status = tx_semaphore_get(&semaphore_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the semaphore. */ + tx_thread_sleep(2); + + /* Release the semaphore. */ + status = tx_semaphore_put(&semaphore_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +void thread_5_entry(ULONG thread_input) +{ + +UINT status; +ULONG actual_flags; + + + /* This thread simply waits for an event in a forever loop. */ + while(1) + { + + /* Increment the thread counter. */ + thread_5_counter++; + + /* Wait for event flag 0. */ + status = tx_event_flags_get(&event_flags_0, 0x1, TX_OR_CLEAR, + &actual_flags, TX_WAIT_FOREVER); + + /* Check status. */ + if ((status != TX_SUCCESS) || (actual_flags != 0x1)) + break; + } +} + + +void thread_6_and_7_entry(ULONG thread_input) +{ + +UINT status; + + + /* This function is executed from thread 6 and thread 7. As the loop + below shows, these function compete for ownership of mutex_0. */ + while(1) + { + + /* Increment the thread counter. */ + if (thread_input == 6) + thread_6_counter++; + else + thread_7_counter++; + + /* Get the mutex with suspension. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Get the mutex again with suspension. This shows + that an owning thread may retrieve the mutex it + owns multiple times. */ + status = tx_mutex_get(&mutex_0, TX_WAIT_FOREVER); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Sleep for 2 ticks to hold the mutex. */ + tx_thread_sleep(2); + + /* Release the mutex. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + + /* Release the mutex again. This will actually + release ownership since it was obtained twice. */ + status = tx_mutex_put(&mutex_0); + + /* Check status. */ + if (status != TX_SUCCESS) + break; + } +} + + +#if 0 +#include + +#include "v7.h" +#include "MP_GIC.h" +#include "MP_Mutexes.h" + + +// compile-time control for the number of CPUs in the cluster +#define nCPUs 4 + +// per-thread space for each CPU for use by the Arm C libraries - will be zero-initialized on start-up +char user_perthread_libspace[ nCPUs ][96]; + + +// Called by the C library to get the address of the per-thread libspace +// Return a separate space for each CPU +void * __user_perthread_libspace(void) +{ + return user_perthread_libspace[ getCPUID() ]; +} + + +// Called by the C library to initialize the mutex to an unlocked state. +// Return a nonzero value to indicate to the C library that it is being used in a multithreaded environment. +int _mutex_initialize(mutex_t *m) +{ + initMutex(m); + return 1; +} + +// Called by the C library to obtain a lock on the mutex. +void _mutex_acquire(mutex_t *m) +{ + lockMutex(m); +} + +// Called by the C library to release the lock on the mutex previously acquired +void _mutex_release(mutex_t *m) +{ + unlockMutex(m); +} + + +/* +The C library startup routine __rt_entry() is called after scatterloading has been performed by __scatterload(). +__rt_entry() attempts a mutex lock call-out as part of its startup. To avoid possible lock-up in systems with +no global exclusive monitors in their memory system, rely on the local monitor provided within MPCore instead. +The local monitor becomes active when the L1 D cache is enabled. So the L1 cache should be enabled after +scatterloading has finished to avoid cache incoherency, but before __rt_entry() executes. This can be achieved +by using the 'wrapper' function which enables the caches then calls the original __rt_entry(). +*/ + +extern void $Super$$__rt_entry(void); + +void $Sub$$__rt_entry(void) +{ + enableBranchPrediction(); + enableCaches(); + + $Super$$__rt_entry(); +} +#endif diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.ld b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.ld new file mode 100644 index 000000000..c2add4f20 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/demo_threadx.ld @@ -0,0 +1,69 @@ +;LOAD 0x0000 0x00100000 +;{ +; STARTUP 0x0000 +; { +; startup.o(StartUp, +FIRST) +; * (InRoot$$Sections) ; Selects all sections that must be in a root region +; * (+RO) +; } +; +; SHARED_DATA +0x0 +; { +; * (+RW,+ZI) +; } +; +; IRQ_STACK 0x001FE000 EMPTY 0x1000 {} +; ARM_LIB_STACKHEAP 0x001FC000 EMPTY 0x2000 {} +;} +; +; +;PAGETABLES 0x00500000 0x00100000 +;{ +; PAGETABLES 0x00500000 EMPTY 0x00100000 +; { +; } +;} + +LOAD_ROOT 0x0 +{ + Root +0 0x10000 + { + startup.o (StartUp, +FIRST) ;startup code + * (InRoot$$Sections) ;All library sections that must be in a root region + + } +} +LOAD 0x48000000 +{ + INIT +0 0x10000 + { + demo_threadx.o (+RO) ; Place main() in a root region for the benefit of software breakpoints + } + + ; increased from 32k to 64k + CODE +0 0x10000 + { + * (+RO) ; Application code, including C library + } + + SHARED_DATA +0 0x4000 + { + * (+RW,+ZI) ; All RW and ZI Data + } + ; App heap for all CPUs + ARM_LIB_HEAP +0 ALIGN 8 EMPTY 0x2000 {} + + ; App stacks for all CPUs - see startup.S + ARM_LIB_STACK +0 ALIGN 8 EMPTY 4*0x1000 {} + + ; IRQ stacks for all CPUs - see startup.s + IRQ_STACK +0 ALIGN 8 EMPTY 4*256 {} + +} + +PAGETABLES 0x00500000 0x00100000 +{ + PAGETABLES 0x00500000 EMPTY 0x00100000 + { + } +} diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/retarget.c b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/retarget.c new file mode 100644 index 000000000..9d3c2cdc3 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/retarget.c @@ -0,0 +1,11 @@ +// Copyright ARM Ltd 2009. All rights reserved. + +extern void $Super$$main(void); +extern void enable_caches(void); + +void $Sub$$main(void) +{ + enable_caches(); // enables caches + $Super$$main(); // calls original main() +} + diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/startup.S b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/startup.S new file mode 100644 index 000000000..58c39a904 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/startup.S @@ -0,0 +1,610 @@ +; ------------------------------------------------------------ +; Cortex-R8 MPCore SMP Prime Number Generator Example +; +; Copyright (c) 2011-2018 Arm Limited (or its affiliates). All rights reserved. +; Use, modification and redistribution of this file is subject to your possession of a +; valid End User License Agreement for the Arm Product of which these examples are part of +; and your compliance with all applicable terms and conditions of such licence agreement. +; ------------------------------------------------------------ + +; MPU region defines + + PRESERVE8 + + AREA StartUp,CODE,READONLY + + +; Region size <256 bytes is unpredictable + +Region_256B EQU 0x07 +Region_512B EQU 0x08 +Region_1K EQU 0x09 +Region_2K EQU 0x0a +Region_4K EQU 0x0b +Region_8K EQU 0x0c +Region_16K EQU 0x0d +Region_32K EQU 0x0e +Region_64K EQU 0x0f +Region_128K EQU 0x10 +Region_256K EQU 0x11 +Region_512K EQU 0x12 +Region_1M EQU 0x13 +Region_2M EQU 0x14 +Region_4M EQU 0x15 +Region_8M EQU 0x16 +Region_16M EQU 0x17 +Region_32M EQU 0x18 +Region_64M EQU 0x19 +Region_128M EQU 0x1a +Region_256M EQU 0x1b +Region_512M EQU 0x1c +Region_1G EQU 0x1d +Region_2G EQU 0x1e +Region_4G EQU 0x1f + +Region_Enable EQU 0x01 +Execute_Never EQU 0x1000 + +Normal_nShared EQU 0x03 ; Outer and Inner write-back, no write-allocate +Device_Shared EQU (0x0<<0x3 :OR: 0x1) +Device_nShared EQU 0x10 + +Full_Access EQU 0x03 +Read_Only EQU 0x06 + +Shared EQU 0x04 + + +; Standard definitions of mode bits and interrupt (I&F) flags in PSRs + +Mode_USR EQU 0x10 +Mode_FIQ EQU 0x11 +Mode_IRQ EQU 0x12 +Mode_SVC EQU 0x13 +Mode_ABT EQU 0x17 +Mode_UND EQU 0x1B +Mode_SYS EQU 0x1F + +I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled +F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled + + +; ------------------------------------------------------------ +; Porting defines +; ------------------------------------------------------------ + +L1_COHERENT EQU 0x00014c06 ; Template descriptor for coherent memory +L1_NONCOHERENT EQU 0x00000c1e ; Template descriptor for non-coherent memory +L1_DEVICE EQU 0x00000c16 ; Template descriptor for device memory + +; ------------------------------------------------------------ + + ENTRY + + EXPORT Vectors + +Vectors + B Reset_Handler + B Undefined_Handler + B SVC_Handler + B Prefetch_Handler + B Abort_Handler + B . ;Reserved vector + B IRQ_Handler + B FIQ_Handler + +; ------------------------------------------------------------ +; Handlers for unused exceptions +; ------------------------------------------------------------ + +Undefined_Handler + B Undefined_Handler +SVC_Handler + B SVC_Handler +Prefetch_Handler + B Prefetch_Handler +Abort_Handler + B Abort_Handler +FIQ_Handler + B FIQ_Handler + +; ------------------------------------------------------------ +; Imports +; ------------------------------------------------------------ + + IMPORT read_irq_ack + IMPORT write_end_of_irq + IMPORT enable_GIC + IMPORT enable_gic_processor_interface + IMPORT set_priority_mask + IMPORT enable_irq_id + IMPORT set_irq_priority + IMPORT enable_scu + IMPORT join_smp + IMPORT secure_SCU_invalidate + IMPORT enable_maintenance_broadcast + IMPORT init_private_timer + IMPORT start_private_timer + IMPORT clear_private_timer_irq + IMPORT __main + + IMPORT __use_two_region_memory + IMPORT ||Image$$IRQ_STACK$$ZI$$Limit|| + +; [EL Change Start] + IMPORT _tx_thread_smp_initialize_wait + IMPORT _tx_thread_smp_release_cores_flag + IMPORT _tx_thread_context_save + IMPORT _tx_thread_context_restore + IMPORT _tx_timer_interrupt + IMPORT _tx_thread_smp_inter_core_interrupts +; [EL Change End] + + +; ------------------------------------------------------------ +; Interrupt Handler +; ------------------------------------------------------------ + + EXPORT IRQ_Handler + EXPORT __tx_irq_processing_return +IRQ_Handler PROC +; [EL Change Start] +; SUB lr, lr, #4 ; Pre-adjust lr +; SRSFD sp!, #Mode_IRQ ; Save lr and SPRS to IRQ mode stack +; PUSH {r0-r4, r12} ; Sace APCS corruptable registers to IRQ mode stack (and maintain 8 byte alignment) +; +; /* Jump to context save to save system context. */ + B _tx_thread_context_save +__tx_irq_processing_return + PUSH {r4, r5} ; Save some preserved registers (r5 is saved just for 8-byte alignment) +; [EL Change End] + + ; Acknowledge the interrupt + BL read_irq_ack + MOV r4, r0 + + ; + ; This example only uses (and enables) one. At this point + ; you would normally check the ID, and clear the source. + ; + + ; + ; Additonal code to handler private timer interrupt on CPU0 + ; + + CMP r0, #29 ; If not Private Timer interrupt (ID 29), by pass + BNE by_pass + +; [EL Change Start] +; MOV r0, #0x04 ; Code for SYS_WRITE0 +; LDR r1, =irq_handler_message0 +; SVC 0x123456 +; [EL Change End] + + ; Clear timer interrupt + BL clear_private_timer_irq + DSB +; [EL Change Start] + BL _tx_timer_interrupt ; Timer interrupt handler +; [EL Change End] + + B by_pass2 + +by_pass + +; [EL Change Start] + ; + ; Additional code to handle SGI on CPU0 + ; +; +; MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register +; ANDS r0, r0, #0x03 ; Mask off, leaving the CPU ID field +; BNE by_pass2 +; +; MOV r0, #0x04 ; Code for SYS_WRITE0 +; LDR r1, =irq_handler_message1 +; SVC 0x123456 +; +; /* Just increment the per-thread interrupt count for analysis purposes. */ +; + MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register + AND r0, r0, #0x03 ; Mask off, leaving the CPU ID field + LSL r0, r0, #2 ; Build offset to array indexes + LDR r1,=_tx_thread_smp_inter_core_interrupts ; Pickup base address of core interrupt counter array + ADD r1, r1, r0 ; Build array index + LDR r0, [r1] ; Pickup counter + ADD r0, r0, #1 ; Increment counter + STR r0, [r1] ; Store back counter +; +; [EL Change End] + + +by_pass2 + ; Write end of interrupt reg + MOV r0, r4 + BL write_end_of_irq + +; [EL Change Start] + +; +; /* Jump to context restore to restore system context. */ + POP {r4, r5} ; Recover preserved registers + B _tx_thread_context_restore + +; POP {r0-r4, r12} ; Restore stacked APCS registers +; MOV r2, #0x01 ; Set r2 so CPU leaves holding pen +; RFEFD sp! ; Return from exception +; [EL Change End] + + ENDP + + +; ------------------------------------------------------------ +; Reset Handler - Generic initialization, run by all CPUs +; ------------------------------------------------------------ + + IMPORT ||Image$$IRQ_STACK$$ZI$$Limit|| + IMPORT ||Image$$ARM_LIB_STACK$$ZI$$Limit|| + IMPORT enable_branch_prediction + IMPORT invalidate_caches + + EXPORT Reset_Handler ; Exported for callgraph purposes! +Reset_Handler PROC + +;---------------------------------------------------------------- +; Disable MPU and caches +;---------------------------------------------------------------- + +; Disable MPU and cache in case it was left enabled from an earlier run +; This does not need to be done from a cold reset + + MRC p15, 0, r0, c1, c0, 0 ; Read System Control Register + BIC r0, r0, #0x05 ; Disable MPU (M bit) and data cache (C bit) + BIC r0, r0, #0x800 ; Disable branch prediction (Z bit) + BIC r0, r0, #0x1000 ; Disable instruction cache (I bit) + DSB ; Ensure all previous loads/stores have completed + MCR p15, 0, r0, c1, c0, 0 ; Write System Control Register + ISB ; Ensure subsequent insts execute wrt new MPU settings + +; [EL Change Start] + ; + ; Setup stacks + ;--------------- +;; MSR CPSR_c, #Mode_IRQ :OR: I_Bit :OR: F_Bit +;; LDR sp, =||Image$$IRQ_STACK$$ZI$$Limit|| +; +;; MSR CPSR_c, #Mode_SYS :OR: I_Bit :OR :F_Bit ; No interrupts +;; LDR sp, =||Image$$ARM_LIB_STACK$$ZI$$Limit|| + + MSR CPSR_c, #Mode_IRQ :OR: I_Bit :OR: F_Bit + LDR sp, =||Image$$IRQ_STACK$$ZI$$Limit|| + + MSR CPSR_c, #Mode_SVC :OR: I_Bit :OR: F_Bit ; No interrupts + LDR sp, =||Image$$ARM_LIB_STACK$$ZI$$Limit|| + + MRC p15, 0, r1, c0, c0, 5 ; Read Multiprocessor Affinity Register + ANDS r1, r1, #0x03 ; Mask off, leaving the CPU ID field + CMP r1,#0 ; Is it core 0? + BEQ _stacks_setup ; +_core_1 + MSR CPSR_c, #Mode_IRQ :OR: I_Bit :OR: F_Bit + MOV r1, #0x800 + SUB sp, sp, r1 + + MSR CPSR_c, #Mode_SVC :OR: I_Bit :OR: F_Bit ; No interrupts + MOV r1, #0x1000 + SUB sp, sp, r1 +_stacks_setup +; [EL Change End] + + ; + ; Invalidate caches + ; ------------------ + BL invalidate_caches + + + ; Clear Branch Prediction Array + ; ------------------------------ + MOV r0, #0x0 + MCR p15, 0, r0, c7, c5, 6 ; BPIALL - Invalidate entire branch predictor array + + + ; + ; Activate VFP/NEON, if required + ;------------------------------- + + IF {TARGET_FPU_VFP} = {TRUE} + + ; Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11. + ; Enables Full Access i.e. in both privileged and non privileged modes + MRC p15, 0, r0, c1, c0, 2 ; Read Coprocessor Access Control Register (CPACR) + ORR r0, r0, #(0xF << 20) ; Enable access to CP 10 & 11 + MCR p15, 0, r0, c1, c0, 2 ; Write Coprocessor Access Control Register (CPACR) + ISB + + ; Switch on the VFP and NEON hardware + MOV r0, #0x40000000 + VMSR FPEXC, r0 ; Write FPEXC register, EN bit set + + ENDIF + +; [EL Change Start] - we don't use the MPU + ;BL configMPU +; [EL Change End] + + ; + ; SMP initialization + ; ------------------- + MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register + ANDS r0, r0, #0x03 ; Mask off, leaving the CPU ID field + BEQ primaryCPUInit + BNE secondaryCPUsInit + + ENDP + + +;---------------------------------------------------------------- +; MPU Configuration +;---------------------------------------------------------------- + + ; Notes: + ; * Regions apply to both instruction and data accesses. + ; * Each region base address must be a multiple of its size + ; * Any address range not covered by an enabled region will abort + ; * The region at 0x0 over the Vector table is needed to support semihosting + + ; Region 0: Init Base = 0x48000000 Size = 64KB Normal Non-shared Full access Executable + ; Region 1: Code Base = 0x48010000 Size = 32KB Normal Non-shared Full access Executable + ; Region 1: Data Base = 0x48018000 Size = 16KB Normal Non-shared Full access Not Executable + ; Region 2: Stack/Heap Base = 0x4801C000 Size = 8KB Normal Non-shared Full access Not Executable + ; Region 4: Vectors Base = 0x0000 Size = 64KB Normal Nonshared Full access Executable + ; Region 5: GIC Base = 0xAE000000 Size = 8KB Device shared Full access Not Executable + + EXPORT +configMPU PROC + + MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register + ANDS r0, r0, #0x03 ; Mask off, leaving the CPU ID field + ; Import linker symbols to get region base addresses + IMPORT ||Image$$INIT$$Base|| + IMPORT ||Image$$CODE$$Base|| + IMPORT ||Image$$SHARED_DATA$$Base|| + IMPORT ||Image$$ARM_LIB_STACK$$Base|| + + ;; Region 0 - Init + MOV r1, #0 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =||Image$$INIT$$Base|| + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_64K << 1) :OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR: Normal_nShared + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + ; Region 1 - Code + ADD r1, r1, #1 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =||Image$$CODE$$Base|| + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_64K << 1) :OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR: Normal_nShared + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + ; Region 2 - Data + ADD r1, r1, #1 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =||Image$$SHARED_DATA$$Base|| + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_16K << 1) :OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR: Normal_nShared :OR: Execute_Never + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + ; Region 3 - Stack/heap + ADD r1, r1, #1 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =||Image$$ARM_LIB_STACK$$Base|| + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_16K << 1) :OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR: Normal_nShared :OR: Execute_Never + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + ; Region 4 - Vectors + ADD r1, r1, #1 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =0 + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_64K << 1) :OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR:Normal_nShared :OR: Shared + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + ; Region 5 - GIC + ADD r1, r1, #1 + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register + ISB ; Ensure subsequent insts execute wrt this region + LDR r2, =0xAE000000 + MCR p15, 0, r2, c6, c1, 0 ; Set region base address register + LDR r2, =0x0 :OR: (Region_8K << 1):OR: Region_Enable + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register + LDR r2, =0x0 :OR: (Full_Access << 8) :OR: Device_Shared :OR: Execute_Never + MCR p15, 0, r2, c6, c1, 4 ; Set region access control register + + + ; Disable all higher priority regions (assumes unified regions, which is always true for Cortex-R8) + MRC p15, 0, r0, c0, c0, 4 ; Read MPU Type register (MPUIR) + LSR r0, r0, #8 + AND r0, r0, #0xff ; r0 = Number of MPU regions (12, 16, 20, or 24 for Cortex-R8) + MOV r2, #0 ; Value to write to disable region +region_loop + ADD r1, r1, #1 + CMP r0, r1 + BLS regions_done + MCR p15, 0, r1, c6, c2, 0 ; Set memory region number register (RGNR) + MCR p15, 0, r2, c6, c1, 2 ; Set region size & enable register (DRSR) + B region_loop +regions_done + BX lr + + ENDP + +; ------------------------------------------------------------ +; Initialization for PRIMARY CPU +; ------------------------------------------------------------ + + EXPORT primaryCPUInit +primaryCPUInit PROC + + ; Enable the SCU + ; --------------- + BL enable_scu + + ; + ; Join SMP + ; --------- + MOV r0, #0x0 ; Move CPU ID into r0 + MOV r1, #0xF ; Move 0xF (represents all four ways) into r1 + BL join_smp + + ; + ; GIC Init + ; --------- + BL enable_GIC + BL enable_gic_processor_interface + +; [EL Change Start] +; /* Leave MPU disabled */ +; ; Enable MPU +; ; ----------- +; ; Leave the caches disabled until after scatter loading. +; MRC p15, 0, r0, c1, c0, 0 ; Read System Control Register +; ORR r0, r0, #0x1 ; Set M bit 0 to enable MMU before scatter loading +; MCR p15, 0, r0, c1, c0, 0 ; Write System Control Register + + ; + ; Enable Private Timer for periodic IRQ + ; -------------------------------------- + MOV r0, #0x1F + BL set_priority_mask ; Set priority mask (local) + + ; [EL] Change start - don't enable interrupts here! + ;CPSIE i ; Clear CPSR I bit + ; [EL] Change end + + ; Enable the Private Timer Interrupt Source + MOV r0, #29 + MOV r1, #0 + BL enable_irq_id + + ; Set the priority + MOV r0, #29 + MOV r1, #0 + BL set_irq_priority + + ; Configure Timer + MOV r0, #0xF0000 + MOV r1, #0x0 + BL init_private_timer + BL start_private_timer + + ; + ; Enable receipt of SGI 0 + ; ------------------------ + MOV r0, #0x0 ; ID + BL enable_irq_id + + MOV r0, #0x0 ; ID + MOV r1, #0x0 ; Priority + BL set_irq_priority +; [EL Change End] + + ; + ; Branch to C lib code + ; ---------------------- + B __main + + ENDP + + + +; ------------------------------------------------------------ +; Initialization for SECONDARY CPUs +; ------------------------------------------------------------ + + EXPORT secondaryCPUsInit +secondaryCPUsInit PROC + +; [EL Change Start] - Don't configure MPU + ;BL configMPU +; [EL Change End] + + ; + ; GIC Init + ; --------- + BL enable_gic_processor_interface + + MOV r0, #0x1F ; Priority + BL set_priority_mask + + MOV r0, #0x0 ; ID + BL enable_irq_id + + MOV r0, #0x0 ; ID + MOV r1, #0x0 ; Priority + BL set_irq_priority + + ; + ; Join SMP + ; --------- + MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register + ANDS r0, r0, #0x03 ; Mask off, leaving the CPU ID field + MOV r1, #0xF ; Move 0xF (represents all four ways) into r1 + BL secure_SCU_invalidate + + BL join_smp + BL enable_maintenance_broadcast + +; [EL Change Start] +; /* Leave MPU disabled */ +; ; Enable MPU +; ; ----------- +; ; Leave the caches disabled until after scatter loading. +; MRC p15, 0, r0, c1, c0, 0 ; Read System Control Register +; ORR r0, r0, #0x1 ; Set M bit 0 to enable MMU before scatter loading +; MCR p15, 0, r0, c1, c0, 0 ; Write System Control Register +; ISB + + ; + ; Holding Pen + ; ------------ +; MOV r2, #0x00 ; Clear r2 +; CPSIE i ; Enable interrupts +;holding_pen +; CMP r2, #0x0 ; r2 will be set to 0x1 by IRQ handler on receiving SGI +; WFIEQ +; BEQ holding_pen +; CPSID i ; IRQs not used in reset of example, so mask out interrupts +;skip +; + ; + ; Branch to C lib code + ; ---------------------- +; B __main + + B _tx_thread_smp_initialize_wait +; [EL Change End] + + ENDP + + END + +; ------------------------------------------------------------ +; End of startup.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.S b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.S new file mode 100644 index 000000000..dfd65a2c5 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.S @@ -0,0 +1,381 @@ +; ------------------------------------------------------------ +; v7 Cache and Branch Prediction Maintenance Operations +; ------------------------------------------------------------ + + PRESERVE8 + + AREA v7CacheOpp,CODE,READONLY + +; ------------------------------------------------------------ +; Cache Maintenance +; ------------------------------------------------------------ + + EXPORT enable_caches + ; void enable_caches(void); +enable_caches PROC + MRC p15, 0, r0, c1, c0, 0 ; Read System Control Register configuration data + ORR r0, r0, #(1 << 2) ; Set C bit + ORR r0, r0, #(1 << 12) ; Set I bit + MCR p15, 0, r0, c1, c0, 0 ; Write System Control Register configuration data + BX lr + ENDP + + + EXPORT disable_caches + ; void disable_caches(void) +disable_caches PROC + MRC p15, 0, r0, c1, c0, 0 ; Read System Control Register configuration data + BIC r0, r0, #(1 << 2) ; Clear C bit + BIC r0, r0, #(1 << 12) ; Clear I bit + MCR p15, 0, r0, c1, c0, 0 ; Write System Control Register configuration data + BX lr + ENDP + + + EXPORT clean_dcache + ; void clean_dcache(void); +clean_dcache PROC + PUSH {r4-r12} + + ; + ; Based on code example given in section 11.2.4 of ARM DDI 0406B + ; + + MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR + ANDS r3, r0, #&7000000 + MOV r3, r3, LSR #23 ; Cache level value (naturally aligned) + BEQ clean_dcache_finished + MOV r10, #0 + +clean_dcache_loop1 + ADD r2, r10, r10, LSR #1 ; Work out 3xcachelevel + MOV r1, r0, LSR r2 ; bottom 3 bits are the Cache type for this level + AND r1, r1, #7 ; get those 3 bits alone + CMP r1, #2 + BLT clean_dcache_skip ; no cache or only instruction cache at this level + MCR p15, 2, r10, c0, c0, 0 ; write the Cache Size selection register + ISB ; ISB to sync the change to the CacheSizeID reg + MRC p15, 1, r1, c0, c0, 0 ; reads current Cache Size ID register + AND r2, r1, #&7 ; extract the line length field + ADD r2, r2, #4 ; add 4 for the line length offset (log2 16 bytes) + LDR r4, =0x3FF + ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned) + CLZ r5, r4 ; R5 is the bit position of the way size increment + LDR r7, =0x00007FFF + ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned) + +clean_dcache_loop2 + MOV r9, R4 ; R9 working copy of the max way size (right aligned) + +clean_dcache_loop3 + ORR r11, r10, r9, LSL r5 ; factor in the way number and cache number into R11 + ORR r11, r11, r7, LSL r2 ; factor in the index number + MCR p15, 0, r11, c7, c10, 2 ; DCCSW - clean by set/way + SUBS r9, r9, #1 ; decrement the way number + BGE clean_dcache_loop3 + SUBS r7, r7, #1 ; decrement the index + BGE clean_dcache_loop2 + +clean_dcache_skip + ADD r10, r10, #2 ; increment the cache number + CMP r3, r10 + BGT clean_dcache_loop1 + +clean_dcache_finished + POP {r4-r12} + + BX lr + ENDP + + EXPORT clean_invalidate_dcache + ; void clean_invalidate_dcache(void); +clean_invalidate_dcache PROC + PUSH {r4-r12} + + ; + ; Based on code example given in section 11.2.4 of ARM DDI 0406B + ; + + MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR + ANDS r3, r0, #&7000000 + MOV r3, r3, LSR #23 ; Cache level value (naturally aligned) + BEQ clean_invalidate_dcache_finished + MOV r10, #0 + +clean_invalidate_dcache_loop1 + ADD r2, r10, r10, LSR #1 ; Work out 3xcachelevel + MOV r1, r0, LSR r2 ; bottom 3 bits are the Cache type for this level + AND r1, r1, #7 ; get those 3 bits alone + CMP r1, #2 + BLT clean_invalidate_dcache_skip ; no cache or only instruction cache at this level + MCR p15, 2, r10, c0, c0, 0 ; write the Cache Size selection register + ISB ; ISB to sync the change to the CacheSizeID reg + MRC p15, 1, r1, c0, c0, 0 ; reads current Cache Size ID register + AND r2, r1, #&7 ; extract the line length field + ADD r2, r2, #4 ; add 4 for the line length offset (log2 16 bytes) + LDR r4, =0x3FF + ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned) + CLZ r5, r4 ; R5 is the bit position of the way size increment + LDR r7, =0x00007FFF + ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned) + +clean_invalidate_dcache_loop2 + MOV r9, R4 ; R9 working copy of the max way size (right aligned) + +clean_invalidate_dcache_loop3 + ORR r11, r10, r9, LSL r5 ; factor in the way number and cache number into R11 + ORR r11, r11, r7, LSL r2 ; factor in the index number + MCR p15, 0, r11, c7, c14, 2 ; DCCISW - clean and invalidate by set/way + SUBS r9, r9, #1 ; decrement the way number + BGE clean_invalidate_dcache_loop3 + SUBS r7, r7, #1 ; decrement the index + BGE clean_invalidate_dcache_loop2 + +clean_invalidate_dcache_skip + ADD r10, r10, #2 ; increment the cache number + CMP r3, r10 + BGT clean_invalidate_dcache_loop1 + +clean_invalidate_dcache_finished + POP {r4-r12} + + BX lr + ENDP + + + EXPORT invalidate_caches + ; void invalidate_caches(void); +invalidate_caches PROC + PUSH {r4-r12} + + ; + ; Based on code example given in section B2.2.4/11.2.4 of ARM DDI 0406B + ; + + MOV r0, #0 + MCR p15, 0, r0, c7, c5, 0 ; ICIALLU - Invalidate entire I Cache, and flushes branch target cache + + MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR + ANDS r3, r0, #&7000000 + MOV r3, r3, LSR #23 ; Cache level value (naturally aligned) + BEQ invalidate_caches_finished + MOV r10, #0 + +invalidate_caches_loop1 + ADD r2, r10, r10, LSR #1 ; Work out 3xcachelevel + MOV r1, r0, LSR r2 ; bottom 3 bits are the Cache type for this level + AND r1, r1, #7 ; get those 3 bits alone + CMP r1, #2 + BLT invalidate_caches_skip ; no cache or only instruction cache at this level + MCR p15, 2, r10, c0, c0, 0 ; write the Cache Size selection register + ISB ; ISB to sync the change to the CacheSizeID reg + MRC p15, 1, r1, c0, c0, 0 ; reads current Cache Size ID register + AND r2, r1, #&7 ; extract the line length field + ADD r2, r2, #4 ; add 4 for the line length offset (log2 16 bytes) + LDR r4, =0x3FF + ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned) + CLZ r5, r4 ; R5 is the bit position of the way size increment + LDR r7, =0x00007FFF + ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned) + +invalidate_caches_loop2 + MOV r9, R4 ; R9 working copy of the max way size (right aligned) + +invalidate_caches_loop3 + ORR r11, r10, r9, LSL r5 ; factor in the way number and cache number into R11 + ORR r11, r11, r7, LSL r2 ; factor in the index number + MCR p15, 0, r11, c7, c6, 2 ; DCISW - invalidate by set/way + SUBS r9, r9, #1 ; decrement the way number + BGE invalidate_caches_loop3 + SUBS r7, r7, #1 ; decrement the index + BGE invalidate_caches_loop2 + +invalidate_caches_skip + ADD r10, r10, #2 ; increment the cache number + CMP r3, r10 + BGT invalidate_caches_loop1 + +invalidate_caches_finished + POP {r4-r12} + BX lr + ENDP + + + EXPORT invalidate_caches_is + ; void invalidate_caches_is(void); +invalidate_caches_is PROC + PUSH {r4-r12} + + MOV r0, #0 + MCR p15, 0, r0, c7, c1, 0 ; ICIALLUIS - Invalidate entire I Cache inner shareable + + MRC p15, 1, r0, c0, c0, 1 ; Read CLIDR + ANDS r3, r0, #&7000000 + MOV r3, r3, LSR #23 ; Cache level value (naturally aligned) + BEQ invalidate_caches_is_finished + MOV r10, #0 + +invalidate_caches_is_loop1 + ADD r2, r10, r10, LSR #1 ; Work out 3xcachelevel + MOV r1, r0, LSR r2 ; bottom 3 bits are the Cache type for this level + AND r1, r1, #7 ; get those 3 bits alone + CMP r1, #2 + BLT invalidate_caches_is_skip ; no cache or only instruction cache at this level + MCR p15, 2, r10, c0, c0, 0 ; write the Cache Size selection register + ISB ; ISB to sync the change to the CacheSizeID reg + MRC p15, 1, r1, c0, c0, 0 ; reads current Cache Size ID register + AND r2, r1, #&7 ; extract the line length field + ADD r2, r2, #4 ; add 4 for the line length offset (log2 16 bytes) + LDR r4, =0x3FF + ANDS r4, r4, r1, LSR #3 ; R4 is the max number on the way size (right aligned) + CLZ r5, r4 ; R5 is the bit position of the way size increment + LDR r7, =0x00007FFF + ANDS r7, r7, r1, LSR #13 ; R7 is the max number of the index size (right aligned) + +invalidate_caches_is_loop2 + MOV r9, R4 ; R9 working copy of the max way size (right aligned) + +invalidate_caches_is_loop3 + ORR r11, r10, r9, LSL r5 ; factor in the way number and cache number into R11 + ORR r11, r11, r7, LSL r2 ; factor in the index number + MCR p15, 0, r11, c7, c6, 2 ; DCISW - clean by set/way + SUBS r9, r9, #1 ; decrement the way number + BGE invalidate_caches_is_loop3 + SUBS r7, r7, #1 ; decrement the index + BGE invalidate_caches_is_loop2 + +invalidate_caches_is_skip + ADD r10, r10, #2 ; increment the cache number + CMP r3, r10 + BGT invalidate_caches_is_loop1 + +invalidate_caches_is_finished + POP {r4-r12} + BX lr + ENDP + +; ------------------------------------------------------------ +; TLB +; ------------------------------------------------------------ + + EXPORT invalidate_unified_tlb + ; void invalidate_unified_tlb(void); +invalidate_unified_tlb PROC + MOV r0, #1 + MCR p15, 0, r0, c8, c7, 0 ; TLBIALL - Invalidate entire unified TLB + BX lr + ENDP + + EXPORT invalidate_unified_tlb_is + ; void invalidate_unified_tlb_is(void); +invalidate_unified_tlb_is PROC + MOV r0, #1 + MCR p15, 0, r0, c8, c3, 0 ; TLBIALLIS - Invalidate entire unified TLB Inner Shareable + BX lr + ENDP + +; ------------------------------------------------------------ +; Branch Prediction +; ------------------------------------------------------------ + + EXPORT enable_branch_prediction + ; void enable_branch_prediction(void) +enable_branch_prediction PROC + MRC p15, 0, r0, c1, c0, 0 ; Read SCTLR + ORR r0, r0, #(1 << 11) ; Set the Z bit (bit 11) + MCR p15, 0,r0, c1, c0, 0 ; Write SCTLR + BX lr + ENDP + + EXPORT disable_branch_prediction + ; void disable_branch_prediction(void) +disable_branch_prediction PROC + MRC p15, 0, r0, c1, c0, 0 ; Read SCTLR + BIC r0, r0, #(1 << 11) ; Clear the Z bit (bit 11) + MCR p15, 0,r0, c1, c0, 0 ; Write SCTLR + BX lr + ENDP + + EXPORT invalidate_branch_target_cache + ; void invalidate_branch_target_cache(void) +invalidate_branch_target_cache PROC + MOV r0, #0 + MCR p15, 0, r0, c7, c5, 6 ; BPIALL - Invalidate entire branch predictor array + BX lr + ENDP + + EXPORT invalidate_branch_target_cache_is + ; void invalidate_branch_target_cache_is(void) +invalidate_branch_target_cache_is PROC + MOV r0, #0 + MCR p15, 0, r0, c7, c1, 6 ; BPIALLIS - Invalidate entire branch predictor array Inner Shareable + BX lr + ENDP + +; ------------------------------------------------------------ +; High Vecs +; ------------------------------------------------------------ + + EXPORT enable_highvecs + ; void enable_highvecs(void); +enable_highvecs PROC + MRC p15, 0, r0, c1, c0, 0 ; Read Control Register + ORR r0, r0, #(1 << 13) ; Set the V bit (bit 13) + MCR p15, 0, r0, c1, c0, 0 ; Write Control Register + BX lr + ENDP + + EXPORT disable_highvecs + ; void disable_highvecs(void); +disable_highvecs PROC + MRC p15, 0, r0, c1, c0, 0 ; Read Control Register + BIC r0, r0, #(1 << 13) ; Clear the V bit (bit 13) + MCR p15, 0, r0, c1, c0, 0 ; Write Control Register + BX lr + ENDP + +; ------------------------------------------------------------ +; Context ID +; ------------------------------------------------------------ + + EXPORT get_context_id + ; uint32_t get_context_id(void); +get_context_id PROC + MRC p15, 0, r0, c13, c0, 1 ; Read Context ID Register + BX lr + ENDP + + EXPORT set_context_id + ; void set_context_id(uint32_t); +set_context_id PROC + MCR p15, 0, r0, c13, c0, 1 ; Write Context ID Register + BX lr + ENDP + +; ------------------------------------------------------------ +; ID registers +; ------------------------------------------------------------ + + EXPORT get_MIDR + ; uint32_t get_MIDR(void); +get_MIDR PROC + MRC p15, 0, r0, c0, c0, 0 ; Read Main ID Register (MIDR) + BX lr + ENDP + + EXPORT get_MPIDR + ; uint32_t get_MPIDR(void); +get_MPIDR PROC + MRC p15, 0, r0, c0 ,c0, 5; Read Multiprocessor ID register (MPIDR) + BX lr + ENDP + +; ------------------------------------------------------------ +; End of code +; ------------------------------------------------------------ + + END + +; ------------------------------------------------------------ +; End of v7.s +; ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.h b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.h new file mode 100644 index 000000000..52a3c6791 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/sample_threadx/v7.h @@ -0,0 +1,117 @@ +// ------------------------------------------------------------ +// v7-A Cache, TLB and Branch Prediction Maintenance Operations +// Header File +// +// Copyright ARM Ltd 2009. All rights reserved. +// ------------------------------------------------------------ + +#ifndef _SEE_V7_h +#define _SEE_V7_h + +#include "kernel.h" + +// +// Note: +// *_is() stands for "inner shareable" +// + +// ------------------------------------------------------------ +// Caches + +void enable_caches(void); +void disable_caches(void); + +void clean_dcache(void); +void clean_invalidate_dcache(void); + +void invalidate_caches(void); +void invalidate_caches_is(void); + +// ------------------------------------------------------------ +// TLBs + +void invalidate_unified_tlb(void); +void invalidate_unified_tlb_is(void); + +// ------------------------------------------------------------ +// Branch prediction + +void enable_branch_prediction(void); +void disable_branch_prediction(void); + +void invalidate_branch_target_cache(void); +void invalidate_branch_target_cache_is(void); + +// ------------------------------------------------------------ +// High Vecs + +void enable_highvecs(void); +void disable_highvecs(void); + +// ------------------------------------------------------------ +// ID Registers + +uint32_t get_MIDR(void); + +#define MIDR_IMPL_SHIFT 24 +#define MIDR_IMPL_MASK 0xFF +#define MIDR_VAR_SHIFT 20 +#define MIDR_VAR_MASK 0xF +#define MIDR_ARCH_SHIFT 16 +#define MIDR_ARCH_MASK 0xF +#define MIDR_PART_SHIFT 4 +#define MIDR_PART_MASK 0xFFF +#define MIDR_REV_SHIFT 0 +#define MIDR_REV_MASK 0xF + +// tmp = get_MIDR(); +// implementor = (tmp >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; +// variant = (tmp >> MIDR_VAR_SHIFT) & MIDR_VAR_MASK; +// architecture= (tmp >> MIDR_ARCH_SHIFT) & MIDR_ARCH_MASK; +// part_number = (tmp >> MIDR_PART_SHIFT) & MIDR_PART_MASK; +// revision = tmp & MIDR_REV_MASK; + +#define MIDR_PART_CA5 0xC05 +#define MIDR_PART_CA8 0xC08 +#define MIDR_PART_CA9 0xC09 + +uint32_t get_MPIDR(void); + +#define MPIDR_FORMAT_SHIFT 31 +#define MPIDR_FORMAT_MASK 0x1 +#define MPIDR_UBIT_SHIFT 30 +#define MPIDR_UBIT_MASK 0x1 +#define MPIDR_CLUSTER_SHIFT 7 +#define MPIDR_CLUSTER_MASK 0xF +#define MPIDR_CPUID_SHIFT 0 +#define MPIDR_CPUID_MASK 0x3 + +#define MPIDR_CPUID_CPU0 0x0 +#define MPIDR_CPUID_CPU1 0x1 +#define MPIDR_CPUID_CPU2 0x2 +#define MPIDR_CPUID_CPU3 0x3 + +#define MPIDR_UNIPROCESSPR 0x1 + +#define MPDIR_NEW_FORMAT 0x1 + +// ------------------------------------------------------------ +// Context ID + +uint32_t get_context_id(void); +void set_context_id(uint32_t); + +#define CONTEXTID_ASID_SHIFT 0 +#define CONTEXTID_ASID_MASK 0xFF +#define CONTEXTID_PROCID_SHIFT 8 +#define CONTEXTID_PROCID_MASK 0x00FFFFFF + +// tmp = get_context_id(); +// ASID = tmp & CONTEXTID_ASID_MASK; +// PROCID = (tmp >> CONTEXTID_PROCID_SHIFT) & CONTEXTID_PROCID_MASK; + +#endif + +// ------------------------------------------------------------ +// End of v7.h +// ------------------------------------------------------------ diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/tx/.cproject b/ports_smp/cortex_r8_smp/ac5/example_build/tx/.cproject new file mode 100644 index 000000000..5aaf33a1c --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/tx/.cproject @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ports_smp/cortex_r8_smp/ac5/example_build/tx/.project b/ports_smp/cortex_r8_smp/ac5/example_build/tx/.project new file mode 100644 index 000000000..106819697 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/example_build/tx/.project @@ -0,0 +1,48 @@ + + + tx + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + inc_generic + 2 + $%7BPARENT-5-PROJECT_LOC%7D/common_smp/inc + + + inc_port + 2 + $%7BPARENT-2-PROJECT_LOC%7D/inc + + + src_generic + 2 + $%7BPARENT-5-PROJECT_LOC%7D/common_smp/src + + + src_port + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + diff --git a/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h b/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h new file mode 100644 index 000000000..1de09e884 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h @@ -0,0 +1,412 @@ +/**************************************************************************/ +/* */ +/* 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 SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + +#ifndef TX_PORT_H +#define TX_PORT_H + + +/************* Define ThreadX SMP constants. *************/ + +/* Define the ThreadX SMP maximum number of cores. */ + +#ifndef TX_THREAD_SMP_MAX_CORES +#define TX_THREAD_SMP_MAX_CORES 2 +#endif + + +/* Define the ThreadX SMP core mask. */ + +#ifndef TX_THREAD_SMP_CORE_MASK +#define TX_THREAD_SMP_CORE_MASK 0x3 /* Where bit 0 represents Core 0, bit 1 represents Core 1, etc. */ +#endif + + +/* Define INLINE_DECLARE to whitespace for ARM compiler. */ + +#define INLINE_DECLARE + + +/* Define dynamic number of cores option. When commented out, the number of cores is static. */ + +/* #define TX_THREAD_SMP_DYNAMIC_CORE_MAX */ + + +/* Define ThreadX SMP initialization macro. */ + +#define TX_PORT_SPECIFIC_PRE_INITIALIZATION + + +/* Define ThreadX SMP pre-scheduler initialization. */ + +#define TX_PORT_SPECIFIC_PRE_SCHEDULER_INITIALIZATION + + +/* Enable the inter-core interrupt logic. */ + +#define TX_THREAD_SMP_INTER_CORE_INTERRUPT + + +/* Determine if there is customer-specific wakeup logic needed. */ + +#ifdef TX_THREAD_SMP_WAKEUP_LOGIC + +/* Include customer-specific wakeup code. */ + +#include "tx_thread_smp_core_wakeup.h" +#else + +#ifdef TX_THREAD_SMP_DEFAULT_WAKEUP_LOGIC + +/* Default wakeup code. */ +#define TX_THREAD_SMP_WAKEUP_LOGIC +#define TX_THREAD_SMP_WAKEUP(i) _tx_thread_smp_core_preempt(i) +#endif +#endif + + +/* Ensure that the in-line resume/suspend define is not allowed. */ + +#ifdef TX_INLINE_THREAD_RESUME_SUSPEND +#undef TX_INLINE_THREAD_RESUME_SUSPEND +#endif + + +/************* End ThreadX SMP constants. *************/ + +/* 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 compiler library include files. */ + +#include +#include + + +/* 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 200 /* 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 + + +/* Define various constants for the ThreadX ARM port. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */ +#else +#define TX_INT_DISABLE 0x80 /* Disable IRQ interrupts */ +#endif +#define TX_INT_ENABLE 0x00 /* Enable IRQ interrupts */ + + +/* 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_MISRA_ENABLE +#ifndef TX_TRACE_TIME_SOURCE +#define TX_TRACE_TIME_SOURCE _tx_thread_smp_time_get() +#endif +#else +#ifndef TX_TRACE_TIME_SOURCE +ULONG _tx_misra_time_stamp_get(VOID); +#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get() +#endif +#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. */ + +#ifdef TX_ENABLE_FIQ_SUPPORT +#define TX_FIQ_ENABLED 1 +#else +#define TX_FIQ_ENABLED 0 +#endif + +#ifdef TX_ENABLE_IRQ_NESTING +#define TX_IRQ_NESTING_ENABLED 2 +#else +#define TX_IRQ_NESTING_ENABLED 0 +#endif + +#ifdef TX_ENABLE_FIQ_NESTING +#define TX_FIQ_NESTING_ENABLED 4 +#else +#define TX_FIQ_NESTING_ENABLED 0 +#endif + +#define TX_PORT_SPECIFIC_BUILD_OPTIONS (TX_FIQ_ENABLED | TX_IRQ_NESTING_ENABLED | TX_FIQ_NESTING_ENABLED) + + +/* Define the in-line initialization constant so that modules with in-line + initialization capabilities can prevent their initialization from being + a function call. */ + +#ifdef TX_MISRA_ENABLE +#define TX_DISABLE_INLINE +#else +#define TX_INLINE_INITIALIZATION +#endif + + +/* 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. */ + +#ifndef TX_MISRA_ENABLE +#ifdef TX_ENABLE_STACK_CHECKING +#undef TX_DISABLE_STACK_FILLING +#endif +#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 ULONG tx_thread_vfp_enable; +#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) + +/* Determine if the ARM architecture has the CLZ instruction. This is available on + architectures v5 and above. If available, redefine the macro for calculating the + lowest bit set. */ + +#ifndef TX_DISABLE_INLINE + +#ifndef __thumb + +#define TX_LOWEST_SET_BIT_CALCULATE(m, b) m = m & ((ULONG) (-((LONG) m))); \ + b = (ULONG) __clz((unsigned int) m); \ + b = 31 - b; +#endif +#endif + + +/************* Define ThreadX SMP data types and function prototypes. *************/ + +struct TX_THREAD_STRUCT; + + +/* Define the ThreadX SMP protection structure. */ + +typedef struct TX_THREAD_SMP_PROTECT_STRUCT +{ + ULONG tx_thread_smp_protect_in_force; + struct TX_THREAD_STRUCT * + tx_thread_smp_protect_thread; + ULONG tx_thread_smp_protect_core; + ULONG tx_thread_smp_protect_count; + + /* Implementation specific information follows. */ + + ULONG tx_thread_smp_protect_get_caller; + ULONG tx_thread_smp_protect_sr; + ULONG tx_thread_smp_protect_release_caller; +} TX_THREAD_SMP_PROTECT; + + +/* 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. */ + +#define TX_INTERRUPT_SAVE_AREA unsigned int interrupt_save; + +#define TX_DISABLE interrupt_save = _tx_thread_smp_protect(); +#define TX_RESTORE _tx_thread_smp_unprotect(interrupt_save); + + +/************* End ThreadX SMP data type and function prototype definitions. *************/ + + +/* 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 VFP extension for the Cortex-A9. Each is assumed to be called in the context of the executing + thread. */ + +void tx_thread_vfp_enable(void); +void tx_thread_vfp_disable(void); + + +/* 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 ARMv7-R SMP Version 6.2.0 *"; +#else +extern CHAR _tx_version_id[]; +#endif + + +#endif + + + + diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_initialize_low_level.s b/ports_smp/cortex_r8_smp/ac5/src/tx_initialize_low_level.s new file mode 100644 index 000000000..86879b015 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/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 */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_system_stack_ptr + IMPORT _tx_initialize_unused_memory + IMPORT _tx_version_id + IMPORT _tx_build_options + IMPORT ||Image$$SHARED_DATA$$ZI$$Limit|| + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_initialize_low_level SMP/Cortex-A8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_initialize_low_level(VOID) +// { + EXPORT _tx_initialize_low_level +_tx_initialize_low_level + + /* Save the first available memory address. */ + // _tx_initialize_unused_memory = (VOID_PTR) (||Image$$SHARED_DATA$$ZI$$Limit||); + + LDR r0, =||Image$$SHARED_DATA$$ZI$$Limit|| // Get end of non-initialized RAM area + LDR r2, =_tx_initialize_unused_memory // Pickup unused memory ptr address + STR r0, [r2, #0] // Save first free memory address + + /* Done, return to caller. */ + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF +// } + + /* Reference build options and version ID to ensure they come in. */ + + LDR r2, =_tx_build_options // Pickup build options variable address + LDR r0, [r2, #0] // Pickup build options content + LDR r2, =_tx_version_id // Pickup version ID variable address + LDR r0, [r2, #0] // Pickup version ID content + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_restore.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_restore.s new file mode 100644 index 000000000..cdc575f88 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_restore.s @@ -0,0 +1,275 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 // Disable IRQ & FIQ interrupts +IRQ_MODE EQU 0xD2 // IRQ mode +SVC_MODE EQU 0xD3 // SVC mode + ELSE +DISABLE_INTS EQU 0x80 // Disable IRQ interrupts +IRQ_MODE EQU 0x92 // IRQ mode +SVC_MODE EQU 0x93 // SVC mode + ENDIF + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_execute_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IMPORT _tx_timer_interrupt_active + IMPORT _tx_thread_smp_protection + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_exit + ENDIF + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_restore SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_restore(VOID) +// { + EXPORT _tx_thread_context_restore +_tx_thread_context_restore + + /* Lockout interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR exit function to indicate an ISR is complete. */ + + BL _tx_execution_isr_exit // Call the ISR exit function + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + + /* Determine if interrupts are nested. */ + // if (--_tx_thread_system_state[core]) + // { + + LDR r3, =_tx_thread_system_state // Pickup address of system state var + ADD r3, r3, r12 // Build array offset + LDR r2, [r3, #0] // Pickup system state + SUB r2, r2, #1 // Decrement the counter + STR r2, [r3, #0] // Store the counter + CMP r2, #0 // Was this the first interrupt? + BEQ __tx_thread_not_nested_restore // If so, not a nested restore + + /* Interrupts are nested. */ + + /* Just recover the saved registers and return to the point of + interrupt. */ + + LDMIA sp!, {r0, r10, r12, lr} // Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 // Put SPSR back + LDMIA sp!, {r0-r3} // Recover r0-r3 + MOVS pc, lr // Return to point of interrupt + + // } +__tx_thread_not_nested_restore + + /* Determine if a thread was interrupted and no preemption is required. */ + //else if (((_tx_thread_current_ptr[core]) && (_tx_thread_current_ptr[core] == _tx_thread_execute_ptr[core]) + // || (_tx_thread_preempt_disable)) + // { + + LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr + ADD r1, r1, r12 // Build index to this core's current thread ptr + LDR r0, [r1, #0] // Pickup actual current thread pointer + CMP r0, #0 // Is it NULL? + BEQ __tx_thread_idle_system_restore // Yes, idle system was interrupted + + LDR r3, =_tx_thread_smp_protection // Get address of protection structure + LDR r2, [r3, #8] // Pickup owning core + CMP r2, r10 // Is the owning core the same as the protected core? + BNE __tx_thread_skip_preempt_check // No, skip the preempt disable check since this is only valid for the owning core + + LDR r3, =_tx_thread_preempt_disable // Pickup preempt disable address + LDR r2, [r3, #0] // Pickup actual preempt disable flag + CMP r2, #0 // Is it set? + BNE __tx_thread_no_preempt_restore // Yes, don't preempt this thread +__tx_thread_skip_preempt_check + + LDR r3, =_tx_thread_execute_ptr // Pickup address of execute thread ptr + ADD r3, r3, r12 // Build index to this core's execute thread ptr + LDR r2, [r3, #0] // Pickup actual execute thread pointer + CMP r0, r2 // Is the same thread highest priority? + BNE __tx_thread_preempt_restore // No, preemption needs to happen + +__tx_thread_no_preempt_restore + + /* Restore interrupted thread or ISR. */ + + /* Pickup the saved stack pointer. */ + // tmp_ptr = _tx_thread_current_ptr[core] -> tx_thread_stack_ptr; + + /* Recover the saved context and return to the point of interrupt. */ + + LDMIA sp!, {r0, r10, r12, lr} // Recover SPSR, POI, and scratch regs + MSR SPSR_cxsf, r0 // Put SPSR back + LDMIA sp!, {r0-r3} // Recover r0-r3 + MOVS pc, lr // Return to point of interrupt + + // } + // else + // { +__tx_thread_preempt_restore + + LDMIA sp!, {r3, r10, r12, lr} // Recover temporarily saved registers + MOV r1, lr // Save lr (point of interrupt) + MOV r2, #SVC_MODE // Build SVC mode CPSR + MSR CPSR_c, r2 // Enter SVC mode + STR r1, [sp, #-4]! // Save point of interrupt + STMDB sp!, {r4-r12, lr} // Save upper half of registers + MOV r4, r3 // Save SPSR in r4 + MOV r2, #IRQ_MODE // Build IRQ mode CPSR + MSR CPSR_c, r2 // Enter IRQ mode + LDMIA sp!, {r0-r3} // Recover r0-r3 + MOV r5, #SVC_MODE // Build SVC mode CPSR + MSR CPSR_c, r5 // Enter SVC mode + STMDB sp!, {r0-r3} // Save r0-r3 on thread's stack + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr + ADD r1, r1, r12 // Build index to current thread ptr + LDR r0, [r1, #0] // Pickup current thread pointer + + IF {TARGET_FPU_VFP} = {TRUE} + LDR r2, [r0, #160] // Pickup the VFP enabled flag + CMP r2, #0 // Is the VFP enabled? + BEQ _tx_skip_irq_vfp_save // No, skip VFP IRQ save + VMRS r2, FPSCR // Pickup the FPSCR + STR r2, [sp, #-4]! // Save FPSCR + VSTMDB sp!, {D0-D15} // Save D0-D15 +_tx_skip_irq_vfp_save + ENDIF + + MOV r3, #1 // Build interrupt stack type + STMDB sp!, {r3, r4} // Save interrupt stack type and SPSR + STR sp, [r0, #8] // Save stack pointer in thread control + // block + + /* Save the remaining time-slice and disable it. */ + // if (_tx_timer_time_slice[core]) + // { + + LDR r3, =_tx_timer_interrupt_active // Pickup timer interrupt active flag's address +_tx_wait_for_timer_to_finish + LDR r2, [r3, #0] // Pickup timer interrupt active flag + CMP r2, #0 // Is the timer interrupt active? + BNE _tx_wait_for_timer_to_finish // If timer interrupt is active, wait until it completes + + LDR r3, =_tx_timer_time_slice // Pickup time-slice variable address + ADD r3, r3, r12 // Build index to core's time slice + LDR r2, [r3, #0] // Pickup time-slice + CMP r2, #0 // Is it active? + BEQ __tx_thread_dont_save_ts // No, don't save it + + // _tx_thread_current_ptr[core] -> tx_thread_time_slice = _tx_timer_time_slice[core]; + // _tx_timer_time_slice[core] = 0; + + STR r2, [r0, #24] // Save thread's time-slice + MOV r2, #0 // Clear value + STR r2, [r3, #0] // Disable global time-slice flag + + // } +__tx_thread_dont_save_ts + + /* Clear the current task pointer. */ + // _tx_thread_current_ptr[core] = TX_NULL; + + MOV r2, #0 // NULL value + STR r2, [r1, #0] // Clear current thread pointer + + /* Set bit indicating this thread is ready for execution. */ + + LDR r2, [r0, #152] // Pickup the ready bit + ORR r2, r2, #0x8000 // Set ready bit (bit 15) + DMB // Ensure that accesses to shared resource have completed + STR r2, [r0, #152] // Make this thread ready for executing again + + /* Return to the scheduler. */ + // _tx_thread_schedule(); + + B _tx_thread_schedule // Return to scheduler + // } + +__tx_thread_idle_system_restore + + /* Just return back to the scheduler! */ + + MOV r3, #SVC_MODE // Build SVC mode with interrupts disabled + MSR CPSR_c, r3 // Change to SVC mode + B _tx_thread_schedule // Return to scheduler +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s new file mode 100644 index 000000000..96448b4a3 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s @@ -0,0 +1,191 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT __tx_irq_processing_return + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_context_save SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_context_save(VOID) +// { + EXPORT _tx_thread_context_save +_tx_thread_context_save + + /* Upon entry to this routine, it is assumed that IRQ interrupts are locked + out, we are in IRQ mode, and all registers are intact. */ + + /* Check for a nested interrupt condition. */ + // if (_tx_thread_system_state[core]++) + // { + + STMDB sp!, {r0-r3} // Save some working registers + + /* Save the rest of the scratch registers on the stack and return to the + calling ISR. */ + + MRS r0, SPSR // Pickup saved SPSR + SUB lr, lr, #4 // Adjust point of interrupt + STMDB sp!, {r0, r10, r12, lr} // Store other registers + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable FIQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + + LDR r3, =_tx_thread_system_state // Pickup address of system state var + ADD r3, r3, r12 // Build index into the system state array + LDR r2, [r3, #0] // Pickup system state + CMP r2, #0 // Is this the first interrupt? + BEQ __tx_thread_not_nested_save // Yes, not a nested context save + + /* Nested interrupt condition. */ + + ADD r2, r2, #1 // Increment the interrupt counter + STR r2, [r3, #0] // Store it back in the variable + + /* Return to the ISR. */ + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + B __tx_irq_processing_return // Continue IRQ processing + +__tx_thread_not_nested_save + // } + + /* Otherwise, not nested, check to see if a thread was running. */ + // else if (_tx_thread_current_ptr[core]) + // { + + ADD r2, r2, #1 // Increment the interrupt counter + STR r2, [r3, #0] // Store it back in the variable + LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr + ADD r1, r1, r12 // Build index into current thread ptr + LDR r0, [r1, #0] // Pickup current thread pointer + CMP r0, #0 // Is it NULL? + BEQ __tx_thread_idle_system_save // If so, interrupt occurred in + // scheduling loop - nothing needs saving! + + /* Save the current stack pointer in the thread's control block. */ + // _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp; + + /* Switch to the system stack. */ + // sp = _tx_thread_system_stack_ptr; + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + B __tx_irq_processing_return // Continue IRQ processing + + // } + // else + // { + +__tx_thread_idle_system_save + + /* Interrupt occurred in the scheduling loop. */ + + /* Not much to do here, just adjust the stack pointer, and return to IRQ + processing. */ + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + ADD sp, sp, #32 // Recover saved registers + B __tx_irq_processing_return // Continue IRQ processing + + // } +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_control.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_control.s new file mode 100644 index 000000000..f76bb3a8d --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_control.s @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT +INT_MASK EQU 0xC0 // Interrupt bit mask + ELSE +INT_MASK EQU 0x80 // Interrupt bit mask + ENDIF + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_control SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_control(UINT new_posture) +// { + EXPORT _tx_thread_interrupt_control +_tx_thread_interrupt_control + + /* Pickup current interrupt lockout posture. */ + + MRS r3, CPSR // Pickup current CPSR + BIC r1, r3, #INT_MASK // Clear interrupt lockout bits + ORR r1, r1, r0 // Or-in new interrupt lockout bits + + /* Apply the new interrupt posture. */ + + MSR CPSR_c, r1 // Setup new CPSR + AND r0, r3, #INT_MASK // Return previous interrupt mask + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_disable.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_disable.s new file mode 100644 index 000000000..3197ab46f --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_disable.s @@ -0,0 +1,85 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_disable SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for disabling interrupts */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// UINT _tx_thread_interrupt_disable(void) +// { + EXPORT _tx_thread_interrupt_disable +_tx_thread_interrupt_disable + + /* Pickup current interrupt lockout posture. */ + + MRS r0, CPSR // Pickup current CPSR + + /* Mask interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ + ELSE + CPSID i // Disable IRQ + ENDIF + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_restore.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_restore.s new file mode 100644 index 000000000..e1419f01e --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_interrupt_restore.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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_interrupt_restore SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is responsible for restoring interrupts to the state */ +/* returned by a previous _tx_thread_interrupt_disable call. */ +/* */ +/* INPUT */ +/* */ +/* old_posture Old interrupt lockout posture */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_interrupt_restore +_tx_thread_interrupt_restore + + /* Apply the new interrupt posture. */ + + MSR CPSR_c, r0 // Setup new CPSR + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_end.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_end.s new file mode 100644 index 000000000..953e8128d --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_end.s @@ -0,0 +1,98 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IF :DEF:TX_ENABLE_FIQ_SUPPORT +DISABLE_INTS EQU 0xC0 // Disable IRQ & FIQ interrupts + ELSE +DISABLE_INTS EQU 0x80 // Disable IRQ interrupts + ENDIF +MODE_MASK EQU 0x1F // Mode mask +IRQ_MODE_BITS EQU 0x12 // IRQ mode bits + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_irq_nesting_end SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called by the application from IRQ mode after */ +/* _tx_thread_irq_nesting_start has been called and switches the IRQ */ +/* processing from system mode back to IRQ mode prior to the ISR */ +/* calling _tx_thread_context_restore. Note that this function */ +/* assumes the system stack pointer is in the same position after */ +/* nesting start function was called. */ +/* */ +/* This function assumes that the system mode stack pointer was setup */ +/* during low-level initialization (tx_initialize_low_level.s). */ +/* */ +/* This function returns with IRQ interrupts disabled. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_irq_nesting_end(VOID) +// { + EXPORT _tx_thread_irq_nesting_end +_tx_thread_irq_nesting_end + MOV r3,lr // Save ISR return address + MRS r0, CPSR // Pickup the CPSR + ORR r0, r0, #DISABLE_INTS // Build disable interrupt value + MSR CPSR_c, r0 // Disable interrupts + LDMIA sp!, {lr, r1} // Pickup saved lr (and r1 throw-away for + // 8-byte alignment logic) + BIC r0, r0, #MODE_MASK // Clear mode bits + ORR r0, r0, #IRQ_MODE_BITS // Build IRQ mode CPSR + MSR CPSR_c, r0 // Re-enter IRQ mode + IF {INTER} = {TRUE} + BX r3 // Return to caller + ELSE + MOV pc, r3 // Return to caller + ENDIF +// } + END + diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_start.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_start.s new file mode 100644 index 000000000..07607ac78 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_irq_nesting_start.s @@ -0,0 +1,92 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +IRQ_DISABLE EQU 0x80 // IRQ disable bit +MODE_MASK EQU 0x1F // Mode mask +SYS_MODE_BITS EQU 0x1F // System mode bits + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_irq_nesting_start SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is called by the application from IRQ mode after */ +/* _tx_thread_context_save has been called and switches the IRQ */ +/* processing to the system mode so nested IRQ interrupt processing */ +/* is possible (system mode has its own "lr" register). Note that */ +/* this function assumes that the system mode stack pointer was setup */ +/* during low-level initialization (tx_initialize_low_level.s). */ +/* */ +/* This function returns with IRQ interrupts enabled. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ISRs */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_irq_nesting_start(VOID) +// { + EXPORT _tx_thread_irq_nesting_start +_tx_thread_irq_nesting_start + MOV r3,lr // Save ISR return address + MRS r0, CPSR // Pickup the CPSR + BIC r0, r0, #MODE_MASK // Clear the mode bits + ORR r0, r0, #SYS_MODE_BITS // Build system mode CPSR + MSR CPSR_c, r0 // Enter system mode + STMDB sp!, {lr, r1} // Push the system mode lr on the system mode stack + // and push r1 just to keep 8-byte alignment + BIC r0, r0, #IRQ_DISABLE // Build enable IRQ CPSR + MSR CPSR_c, r0 // Enter system mode + IF {INTER} = {TRUE} + BX r3 // Return to caller + ELSE + MOV pc, r3 // Return to caller + ENDIF +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_schedule.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_schedule.s new file mode 100644 index 000000000..ebb0ca5c8 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_schedule.s @@ -0,0 +1,249 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_execute_ptr + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_enter + ENDIF + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_schedule SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_schedule(VOID) +// { + EXPORT _tx_thread_schedule +_tx_thread_schedule + + /* Enable interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSIE if // Enable IRQ and FIQ interrupts + ELSE + CPSIE i // Enable IRQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + + LDR r1, =_tx_thread_execute_ptr // Address of thread execute ptr + ADD r1, r1, r12 // Build offset to execute ptr for this core + + /* Lockout interrupts transfer control to it. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + /* Wait for a thread to execute. */ + // do + // { + + LDR r0, [r1, #0] // Pickup next thread to execute + CMP r0, #0 // Is it NULL? + BEQ _tx_thread_schedule // If so, keep looking for a thread + + // } + // while(_tx_thread_execute_ptr[core] == TX_NULL); + + /* Now make sure the thread's ready bit is set. */ + + LDR r2, [r0, #152] // Pickup the thread ready bit + AND r3, r2, #0x8000 // Isolate the ready bit + CMP r3, #0 // Is it set? + BEQ _tx_thread_schedule // If not, restart the scheduling loop + + /* Yes! We have a thread to execute. ; + + /* Clear the ready bit. */ + + BIC r2, r2, #0x8000 // Clear ready bit + STR r2, [r0, #152] // Store it back in the thread control block + DMB + + /* Setup the current thread pointer. */ + // _tx_thread_current_ptr[core] = _tx_thread_execute_ptr[core]; + + LDR r1, =_tx_thread_current_ptr // Pickup address of current thread + ADD r1, r1, r12 // Build index into the current thread array + STR r0, [r1, #0] // Setup current thread pointer + + /* Increment the run count for this thread. */ + // _tx_thread_current_ptr[core] -> tx_thread_run_count++; + + LDR r2, [r0, #4] // Pickup run counter + LDR r3, [r0, #24] // Pickup time-slice for this thread + ADD r2, r2, #1 // Increment thread run-counter + STR r2, [r0, #4] // Store the new run counter + + /* Setup time-slice, if present. */ + // _tx_timer_time_slice[core] = _tx_thread_current_ptr[core] -> tx_thread_time_slice; + + LDR r2, =_tx_timer_time_slice // Pickup address of time slice + // variable + ADD r2, r2, r12 // Build index into the time-slice array + LDR sp, [r0, #8] // Switch stack pointers + STR r3, [r2, #0] // Setup time-slice + + /* Switch to the thread's stack. */ + // sp = _tx_thread_execute_ptr[core] -> tx_thread_stack_ptr; + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the thread entry function to indicate the thread is executing. */ + + MOV r5, r0 // Save r0 + BL _tx_execution_thread_enter // Call the thread execution enter function + MOV r0, r5 // Restore r0 + ENDIF + + /* Determine if an interrupt frame or a synchronous task suspension frame + is present. */ + + LDMIA sp!, {r4, r5} // Pickup the stack type and saved CPSR + CMP r4, #0 // Check for synchronous context switch + BEQ _tx_solicited_return + MSR SPSR_cxsf, r5 // Setup SPSR for return + IF {TARGET_FPU_VFP} = {TRUE} + LDR r1, [r0, #160] // Pickup the VFP enabled flag + CMP r1, #0 // Is the VFP enabled? + BEQ _tx_skip_interrupt_vfp_restore // No, skip VFP interrupt restore + VLDMIA sp!, {D0-D15} // Recover D0-D15 + LDR r4, [sp], #4 // Pickup FPSCR + VMSR FPSCR, r4 // Restore FPSCR +_tx_skip_interrupt_vfp_restore + ENDIF + LDMIA sp!, {r0-r12, lr, pc}^ // Return to point of thread interrupt + +_tx_solicited_return + IF {TARGET_FPU_VFP} = {TRUE} + MSR CPSR_cxsf, r5 // Recover CPSR + LDR r1, [r0, #160] // Pickup the VFP enabled flag + CMP r1, #0 // Is the VFP enabled? + BEQ _tx_skip_solicited_vfp_restore // No, skip VFP solicited restore + VLDMIA sp!, {D0-D15} // Recover D0-D15 + LDR r4, [sp], #4 // Pickup FPSCR + VMSR FPSCR, r4 // Restore FPSCR +_tx_skip_solicited_vfp_restore + ENDIF + MSR CPSR_cxsf, r5 // Recover CPSR + LDMIA sp!, {r4-r11, lr} // Return to thread synchronously + BX lr // Return to caller + +// } + + + IF {TARGET_FPU_VFP} = {TRUE} + EXPORT tx_thread_vfp_enable +tx_thread_vfp_enable + MRS r2, CPSR // Pickup the CPSR + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + MRC p15, 0, r1, c0, c0, 5 // Read CPU ID register + AND r1, r1, #0x03 // Mask off, leaving the CPU ID field + LSL r1, r1, #2 // Build offset to array indexes + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + ADD r0, r0, r1 // Build index into the current thread array + LDR r1, [r0] // Pickup current thread pointer + CMP r1, #0 // Check for NULL thread pointer + BEQ __tx_no_thread_to_enable // If NULL, skip VFP enable + MOV r0, #1 // Build enable value + STR r0, [r1, #160] // Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) +__tx_no_thread_to_enable + MSR CPSR_cxsf, r2 // Recover CPSR + BX LR // Return to caller + + EXPORT tx_thread_vfp_disable +tx_thread_vfp_disable + MRS r2, CPSR // Pickup the CPSR + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + MRC p15, 0, r1, c0, c0, 5 // Read CPU ID register + AND r1, r1, #0x03 // Mask off, leaving the CPU ID field + LSL r1, r1, #2 // Build offset to array indexes + LDR r0, =_tx_thread_current_ptr // Build current thread pointer address + ADD r0, r0, r1 // Build index into the current thread array + LDR r1, [r0] // Pickup current thread pointer + CMP r1, #0 // Check for NULL thread pointer + BEQ __tx_no_thread_to_disable // If NULL, skip VFP disable + MOV r0, #0 // Build disable value + STR r0, [r1, #160] // Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD) +__tx_no_thread_to_disable + MSR CPSR_cxsf, r2 // Recover CPSR + BX LR // Return to caller + ENDIF + +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_get.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_get.s new file mode 100644 index 000000000..bd9177923 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_get.s @@ -0,0 +1,72 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_core_get SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the currently running core number and returns it.*/ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* Core ID */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Source */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_core_get +_tx_thread_smp_core_get + MRC p15, 0, r0, c0, c0, 5 // Read CPU ID register + AND r0, r0, #0x03 // Mask off, leaving the CPU ID field + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_preempt.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_preempt.s new file mode 100644 index 000000000..20a6ab296 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_core_preempt.s @@ -0,0 +1,89 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT send_sgi + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_core_preempt SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function preempts the specified core in situations where the */ +/* thread corresponding to this core is no longer ready or when the */ +/* core must be used for a higher-priority thread. If the specified is */ +/* the current core, this processing is skipped since the will give up */ +/* control subsequently on its own. */ +/* */ +/* INPUT */ +/* */ +/* core The core to preempt */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Source */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_core_preempt +_tx_thread_smp_core_preempt + + STMDB sp!, {lr, r4} // Save the lr and r4 register on the stack + + /* Place call to send inter-processor interrupt here! */ + + DSB // + MOV r1, #1 // Build parameter list + LSL r1, r1, r0 // + MOV r0, #0 // + MOV r2, #0 // + BL send_sgi // Make call to send inter-processor interrupt + + LDMIA sp!, {lr, r4} // Recover lr register and r4 + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_state_get.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_state_get.s new file mode 100644 index 000000000..32bcb44e5 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_state_get.s @@ -0,0 +1,91 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_system_state + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_current_state_get SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is gets the current state of the calling core. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_current_state_get +_tx_thread_smp_current_state_get + + MRS r3, CPSR // Pickup current CPSR + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r2, c0, c0, 5 // Read CPU ID register + AND r2, r2, #0x03 // Mask off, leaving the CPU ID field + LSL r2, r2, #2 // Build offset to array indexes + + LDR r1, =_tx_thread_system_state // Pickup start of the current state array + ADD r1, r1, r2 // Build index into the current state array + LDR r0, [r1] // Pickup state for this core + MSR CPSR_c, r3 // Restore CPSR + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_thread_get.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_thread_get.s new file mode 100644 index 000000000..0e50c725d --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_current_thread_get.s @@ -0,0 +1,90 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + IMPORT _tx_thread_current_ptr + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_current_thread_get SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is gets the current thread of the calling core. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Components */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_current_thread_get +_tx_thread_smp_current_thread_get + + MRS r3, CPSR // Pickup current CPSR + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r2, c0, c0, 5 // Read CPU ID register + AND r2, r2, #0x03 // Mask off, leaving the CPU ID field + LSL r2, r2, #2 // Build offset to array indexes + + LDR r1, =_tx_thread_current_ptr // Pickup start of the current thread array + ADD r1, r1, r2 // Build index into the current thread array + LDR r0, [r1] // Pickup current thread for this core + MSR CPSR_c, r3 // Restore CPSR + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_initialize_wait.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_initialize_wait.s new file mode 100644 index 000000000..e7befb3d1 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_initialize_wait.s @@ -0,0 +1,128 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_smp_release_cores_flag + IMPORT _tx_thread_schedule + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_initialize_wait SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is the place where additional cores wait until */ +/* initialization is complete before they enter the thread scheduling */ +/* loop. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* _tx_thread_schedule Thread scheduling loop */ +/* */ +/* CALLED BY */ +/* */ +/* Hardware */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_initialize_wait +_tx_thread_smp_initialize_wait + + /* Lockout interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r10, r10, #2 // Build offset to array indexes + + /* Make sure the system state for this core is TX_INITIALIZE_IN_PROGRESS before we check the release + flag. */ + + LDR r3, =_tx_thread_system_state // Build address of system state variable + ADD r3, r3, r10 // Build index into the system state array + LDR r2, =0xF0F0F0F0 // Build TX_INITIALIZE_IN_PROGRESS flag +wait_for_initialize + LDR r1, [r3] // Pickup system state + CMP r1, r2 // Has initialization completed? + BNE wait_for_initialize // If different, wait here! + + /* Pickup the release cores flag. */ + + LDR r2, =_tx_thread_smp_release_cores_flag // Build address of release cores flag + +wait_for_release + LDR r3, [r2] // Pickup the flag + CMP r3, #0 // Is it set? + BEQ wait_for_release // Wait for the flag to be set + + /* Core 0 has released this core. */ + + /* Clear this core's system state variable. */ + + LDR r3, =_tx_thread_system_state // Build address of system state variable + ADD r3, r3, r10 // Build index into the system state array + MOV r0, #0 // Build clear value + STR r0, [r3] // Clear this core's entry in the system state array + + /* Now wait for core 0 to finish it's initialization. */ + + LDR r3, =_tx_thread_system_state // Build address of system state variable of logical 0 + +core_0_wait_loop + LDR r2, [r3] // Pickup system state for core 0 + CMP r2, #0 // Is it 0? + BNE core_0_wait_loop // No, keep waiting for core 0 to finish its initialization + + /* Initialize is complete, enter the scheduling loop! */ + + B _tx_thread_schedule // Enter scheduling loop for this core! + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_low_level_initialize.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_low_level_initialize.s new file mode 100644 index 000000000..b5edd74b8 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_low_level_initialize.s @@ -0,0 +1,72 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_low_level_initialize SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function performs low-level initialization of the booting */ +/* core. */ +/* */ +/* INPUT */ +/* */ +/* number_of_cores Number of cores */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_initialize_high_level ThreadX high-level init */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_low_level_initialize +_tx_thread_smp_low_level_initialize + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_protect.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_protect.s new file mode 100644 index 000000000..11b811284 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_protect.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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_smp_protection + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_protect SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets protection for running inside the ThreadX */ +/* source. This is acomplished by a combination of a test-and-set */ +/* flag and periodically disabling interrupts. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* Previous Status Register */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Source */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_protect +_tx_thread_smp_protect + + MRS r3, CPSR // Pickup current CPSR + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r2, c0, c0, 5 // Read CPU ID register + AND r2, r2, #0x03 // Mask off, leaving the CPU ID field + LDR r0,=_tx_thread_smp_protection // Build address to protection structure + LDR r1, [r0, #8] // Pickup the owning core + CMP r1, r2 // Is it this core? + BEQ _owned // Yes, the protection is already owned + + LDREX r1, [r0] // Pickup the protection + CMP r1, #0 // Is it available? + BEQ _get_protection // Yes, get the protection + MSR CPSR_c, r3 // Restore CPSR + WFE // Go into standby + B _tx_thread_smp_protect // On waking restart the protection attempt + +_get_protection + MOV r1, #1 // Build lock value + STREX r2, r1, [r0] // Attempt to get protection + CMP r2, #0x0 // Check whether store completed successfully (0=succeeded) + MSRNE CPSR_c, r3 // If unsuccessful, restore CPSR + BNE _tx_thread_smp_protect // If unsuccessful, try the process again! + DMB ; + MRC p15, 0, r2, c0, c0, 5 // Read CPU ID register + AND r2, r2, #0x03 // Mask off, leaving the CPU ID field + STR r2, [r0, #8] // Save owning core + + IF :DEF:TX_MPCORE_DEBUG_ENABLE + LSL r2, r2, #2 // Build offset to array indexes + LDR r1, =_tx_thread_current_ptr // Pickup start of the current thread array + ADD r1, r1, r2 // Build index into the current thread array + LDR r2, [r1] // Pickup current thread for this core + STR r2, [r0, #4] // Save current thread pointer + STR LR, [r0, #16] // Save caller's return address + STR r3, [r0, #20] // Save CPSR + ENDIF +_owned + LDR r1, [r0, #12] // Pickup ownership count + ADD r1, r1, #1 // Increment ownership count + STR r1, [r0, #12] // Store new ownership count + + MOV r0, r3 // Return the CPSR + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s new file mode 100644 index 000000000..fdaab14bc --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s @@ -0,0 +1,75 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_time_get SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function gets the global time value that is used for debug */ +/* information and event tracing. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* 32-bit time stamp */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Source */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_time_get +_tx_thread_smp_time_get + + MRC p15, 4, r0, c15, c0, 0 // Read periph base address + LDR r0, [r0, #0x604] // Read count register + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_unprotect.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_unprotect.s new file mode 100644 index 000000000..b431e485a --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_unprotect.s @@ -0,0 +1,119 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_current_ptr + IMPORT _tx_thread_smp_protection + IMPORT _tx_thread_preempt_disable + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_smp_unprotect SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function releases previously obtained protection. The supplied */ +/* previous SR is restored. If the value of _tx_thread_system_state */ +/* and _tx_thread_preempt_disable are both zero, then multithreading */ +/* is enabled as well. */ +/* */ +/* INPUT */ +/* */ +/* Previous Status Register */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* ThreadX Source */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ + EXPORT _tx_thread_smp_unprotect +_tx_thread_smp_unprotect + + /* Lockout interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + LDR r1,=_tx_thread_smp_protection // Build address of protection structure + MRC p15, 0, r3, c0, c0, 5 // Read CPU ID register + AND r3, r3, #0x03 // Mask off, leaving the CPU ID field + LDR r2, [r1, #8] // Pickup the owning core + CMP r2, r3 // Is it this core? + BNE _still_protected // If this is not the owning core, protection is in force elsewhere + + LDR r2, [r1, #12] // Pickup the protection count + CMP r2, #0 // Check to see if the protection is still active + BEQ _still_protected // If the protection count is zero, protection has already been cleared + + SUB r2, r2, #1 // Decrement the protection count + STR r2, [r1, #12] // Store the new count back + CMP r2, #0 // Check to see if the protection is still active + BNE _still_protected // If the protection count is non-zero, protection is still in force + LDR r2,=_tx_thread_preempt_disable // Build address of preempt disable flag + LDR r3, [r2] // Pickup preempt disable flag + CMP r3, #0 // Is the preempt disable flag set? + BNE _still_protected // Yes, skip the protection release + MOV r2, #0xFFFFFFFF // Build invalid value + STR r2, [r1, #8] // Mark the protected core as invalid + IF :DEF:TX_MPCORE_DEBUG_ENABLE + STR LR, [r0, #16] // Save caller's return address + ENDIF + DMB // Ensure that accesses to shared resource have completed + MOV r2, #0 // Build release protection value + STR r2, [r1] // Release the protection + DSB // To ensure update of the protection occurs before other CPUs awake + SEV // Send event to other CPUs, wakes anyone waiting on the protection (using WFE) + +_still_protected + MSR CPSR_c, r0 // Restore CPSR + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_stack_build.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_stack_build.s new file mode 100644 index 000000000..425bc4e9f --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_stack_build.s @@ -0,0 +1,159 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +SVC_MODE EQU 0x13 // SVC mode + IF :DEF:TX_ENABLE_FIQ_SUPPORT +CPSR_MASK EQU 0xDF // Mask initial CPSR, IRQ & FIQ ints enabled + ELSE +CPSR_MASK EQU 0x9F // Mask initial CPSR, IRQ ints enabled + ENDIF + +THUMB_BIT EQU 0x20 // Thumb-bit + + AREA ||.text||, CODE, READONLY +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_stack_build SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID)) +// { + EXPORT _tx_thread_stack_build +_tx_thread_stack_build + + + /* Build a fake interrupt frame. The form of the fake interrupt stack + on the Cortex-R8 should look like the following after it is built: + + Stack Top: 1 Interrupt stack frame type + CPSR Initial value for CPSR + a1 (r0) Initial value for a1 + a2 (r1) Initial value for a2 + a3 (r2) Initial value for a3 + a4 (r3) Initial value for a4 + v1 (r4) Initial value for v1 + v2 (r5) Initial value for v2 + v3 (r6) Initial value for v3 + v4 (r7) Initial value for v4 + v5 (r8) Initial value for v5 + sb (r9) Initial value for sb + sl (r10) Initial value for sl + fp (r11) Initial value for fp + ip (r12) Initial value for ip + lr (r14) Initial value for lr + pc (r15) Initial value for pc + 0 For stack backtracing + + Stack Bottom: (higher memory address) */ + + LDR r2, [r0, #16] // Pickup end of stack area + BIC r2, r2, #7 // Ensure 8-byte alignment + SUB r2, r2, #76 // Allocate space for the stack frame + + /* Actually build the stack frame. */ + + MOV r3, #1 // Build interrupt stack type + STR r3, [r2, #0] // Store stack type + MOV r3, #0 // Build initial register value + STR r3, [r2, #8] // Store initial r0 + STR r3, [r2, #12] // Store initial r1 + STR r3, [r2, #16] // Store initial r2 + STR r3, [r2, #20] // Store initial r3 + STR r3, [r2, #24] // Store initial r4 + STR r3, [r2, #28] // Store initial r5 + STR r3, [r2, #32] // Store initial r6 + STR r3, [r2, #36] // Store initial r7 + STR r3, [r2, #40] // Store initial r8 + STR r3, [r2, #44] // Store initial r9 + LDR r3, [r0, #12] // Pickup stack starting address + STR r3, [r2, #48] // Store initial r10 (sl) + MOV r3, #0 // Build initial register value + STR r3, [r2, #52] // Store initial r11 + STR r3, [r2, #56] // Store initial r12 + STR r3, [r2, #60] // Store initial lr + STR r1, [r2, #64] // Store initial pc + STR r3, [r2, #68] // 0 for back-trace + + MRS r3, CPSR // Pickup CPSR + BIC r3, r3, #CPSR_MASK // Mask mode bits of CPSR + ORR r3, r3, #SVC_MODE // Build CPSR, SVC mode, interrupts enabled + BIC r3, r3, #THUMB_BIT // Clear Thumb-bit by default + AND r1, r1, #1 // Determine if the entry function is in Thumb mode + CMP r1, #1 // Is the Thumb-bit set? + ORREQ r3, r3, #THUMB_BIT // Yes, set the Thumb-bit + STR r3, [r2, #4] // Store initial CPSR + + /* Setup stack pointer. */ + // thread_ptr -> tx_thread_stack_ptr = r2; + + STR r2, [r0, #8] // Save stack pointer in thread's + // control block + + + /* Set ready bit in thread control block. */ + + LDR r2, [r0, #152] // Pickup word with ready bit + ORR r2, r2, #0x8000 // Build ready bit set + STR r2, [r0, #152] // Set ready bit + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF +// } + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s new file mode 100644 index 000000000..1803e190e --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s @@ -0,0 +1,193 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_current_ptr + IMPORT _tx_timer_time_slice + IMPORT _tx_thread_schedule + IMPORT _tx_thread_preempt_disable + IMPORT _tx_thread_smp_protection + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_thread_exit + ENDIF + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_system_return SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function is target processor specific. It is used to transfer */ +/* control from a thread back to the ThreadX 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_system_return(VOID) +// { + EXPORT _tx_thread_system_return +_tx_thread_system_return + + /* Save minimal context on the stack. */ + + STMDB sp!, {r4-r11, lr} // Save minimal context + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + + LDR r3, =_tx_thread_current_ptr // Pickup address of current ptr + ADD r3, r3, r12 // Build index into current ptr array + LDR r0, [r3, #0] // Pickup current thread pointer + IF {TARGET_FPU_VFP} = {TRUE} + LDR r1, [r0, #160] // Pickup the VFP enabled flag + CMP r1, #0 // Is the VFP enabled? + BEQ _tx_skip_solicited_vfp_save // No, skip VFP solicited save + VMRS r4, FPSCR // Pickup the FPSCR + STR r4, [sp, #-4]! // Save FPSCR + VSTMDB sp!, {D0-D15} // Save D0-D15 +_tx_skip_solicited_vfp_save + ENDIF + MOV r4, #0 // Build a solicited stack type + MRS r5, CPSR // Pickup the CPSR + STMDB sp!, {r4-r5} // Save type and CPSR + + /* Lockout interrupts. */ + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ELSE + CPSID i // Disable IRQ interrupts + ENDIF + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the thread exit function to indicate the thread is no longer executing. */ + + MOV r4, r0 // Save r0 + MOV r5, r3 // Save r3 + MOV r6, r12 // Save r12 + BL _tx_execution_thread_exit // Call the thread exit function + MOV r3, r5 // Recover r3 + MOV r0, r4 // Recover r4 + MOV r12,r6 // Recover r12 + ENDIF + + LDR r2, =_tx_timer_time_slice // Pickup address of time slice + ADD r2, r2, r12 // Build index into time-slice array + LDR r1, [r2, #0] // Pickup current time slice + + /* Save current stack and switch to system stack. */ + // _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp; + // sp = _tx_thread_system_stack_ptr[core]; + + STR sp, [r0, #8] // Save thread stack pointer + + /* Determine if the time-slice is active. */ + // if (_tx_timer_time_slice[core]) + // { + + MOV r4, #0 // Build clear value + CMP r1, #0 // Is a time-slice active? + 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[core] -> tx_thread_time_slice = _tx_timer_time_slice[core]; + // _tx_timer_time_slice[core] = 0; + + STR r4, [r2, #0] // Clear time-slice + STR r1, [r0, #24] // Save current time-slice + + // } +__tx_thread_dont_save_ts + + /* Clear the current thread pointer. */ + // _tx_thread_current_ptr[core] = TX_NULL; + + STR r4, [r3, #0] // Clear current thread pointer + + /* Set ready bit in thread control block. */ + + LDR r2, [r0, #152] // Pickup word with ready bit + ORR r2, r2, #0x8000 // Build ready bit set + DMB // Ensure that accesses to shared resource have completed + STR r2, [r0, #152] // Set ready bit + + /* Now clear protection. It is assumed that protection is in force whenever this routine is called. */ + + LDR r3, =_tx_thread_smp_protection // Pickup address of protection structure + + IF :DEF:TX_MPCORE_DEBUG_ENABLE + STR lr, [r3, #24] // Save last caller + LDR r2, [r3, #4] // Pickup owning thread + CMP r0, r2 // Is it the same as the current thread? +__error_loop + BNE __error_loop // If not, we have a problem!! + ENDIF + + LDR r1, =_tx_thread_preempt_disable // Build address to preempt disable flag + MOV r2, #0 // Build clear value + STR r2, [r1, #0] // Clear preempt disable flag + STR r2, [r3, #12] // Clear protection count + MOV r1, #0xFFFFFFFF // Build invalid value + STR r1, [r3, #8] // Set core to an invalid value + DMB // Ensure that accesses to shared resource have completed + STR r2, [r3] // Clear protection + DSB // To ensure update of the shared resource occurs before other CPUs awake + SEV // Send event to other CPUs, wakes anyone waiting on a mutex (using WFE) + + B _tx_thread_schedule // Jump to scheduler! + +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s new file mode 100644 index 000000000..1aa88bcbd --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s @@ -0,0 +1,197 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_thread_system_state + IMPORT _tx_thread_current_ptr + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + IMPORT _tx_execution_isr_enter + ENDIF + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_vectored_context_save SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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 */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_thread_vectored_context_save(VOID) +// { + EXPORT _tx_thread_vectored_context_save +_tx_thread_vectored_context_save + + /* Upon entry to this routine, it is assumed that IRQ interrupts are locked + out, we are in IRQ mode, and all registers are intact. */ + + /* Check for a nested interrupt condition. */ + // if (_tx_thread_system_state[core]++) + // { + + IF :DEF:TX_ENABLE_FIQ_SUPPORT + CPSID if // Disable IRQ and FIQ interrupts + ENDIF + + /* Pickup the CPU ID. */ + + MRC p15, 0, r10, c0, c0, 5 // Read CPU ID register + AND r10, r10, #0x03 // Mask off, leaving the CPU ID field + LSL r12, r10, #2 // Build offset to array indexes + + LDR r3, =_tx_thread_system_state // Pickup address of system state var + ADD r3, r3, r12 // Build index into the system state array + LDR r2, [r3, #0] // Pickup system state + CMP r2, #0 // Is this the first interrupt? + BEQ __tx_thread_not_nested_save // Yes, not a nested context save + + /* Nested interrupt condition. */ + + ADD r2, r2, #1 // Increment the interrupt counter + STR r2, [r3, #0] // Store it back in the variable + + /* Note: Minimal context of interrupted thread is already saved. */ + + /* Return to the ISR. */ + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + +__tx_thread_not_nested_save + // } + + /* Otherwise, not nested, check to see if a thread was running. */ + // else if (_tx_thread_current_ptr[core]) + // { + + ADD r2, r2, #1 // Increment the interrupt counter + STR r2, [r3, #0] // Store it back in the variable + LDR r1, =_tx_thread_current_ptr // Pickup address of current thread ptr + ADD r1, r1, r12 // Build index into current thread ptr + LDR r0, [r1, #0] // Pickup current thread pointer + CMP r0, #0 // Is it NULL? + BEQ __tx_thread_idle_system_save // If so, interrupt occurred in + // scheduling loop - nothing needs saving! + + /* Note: Minimal context of interrupted thread is already saved. */ + + /* Save the current stack pointer in the thread's control block. */ + // _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp; + + /* Switch to the system stack. */ + // sp = _tx_thread_system_stack_ptr[core]; + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + // } + // else + // { + +__tx_thread_idle_system_save + + /* Interrupt occurred in the scheduling loop. */ + + /* Not much to do here, just adjust the stack pointer, and return to IRQ + processing. */ + + MOV r10, #0 // Clear stack limit + + IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY + + /* Call the ISR enter function to indicate an ISR is executing. */ + + PUSH {r12, lr} // Save ISR lr & r12 + BL _tx_execution_isr_enter // Call the ISR enter function + POP {r12, lr} // Recover ISR lr & r12 + ENDIF + + ADD sp, sp, #32 // Recover saved registers + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + + // } +// } + + END diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_timer_interrupt.s b/ports_smp/cortex_r8_smp/ac5/src/tx_timer_interrupt.s new file mode 100644 index 000000000..875482657 --- /dev/null +++ b/ports_smp/cortex_r8_smp/ac5/src/tx_timer_interrupt.s @@ -0,0 +1,214 @@ +/**************************************************************************/ +/* */ +/* 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 */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + + IMPORT _tx_timer_time_slice + IMPORT _tx_timer_system_clock + IMPORT _tx_timer_current_ptr + IMPORT _tx_timer_list_start + IMPORT _tx_timer_list_end + IMPORT _tx_timer_expired_time_slice + IMPORT _tx_timer_expired + IMPORT _tx_thread_time_slice + IMPORT _tx_timer_expiration_process + IMPORT _tx_timer_interrupt_active + IMPORT _tx_thread_smp_protect + IMPORT _tx_thread_smp_unprotect + IMPORT _tx_trace_isr_enter_insert + IMPORT _tx_trace_isr_exit_insert + + AREA ||.text||, CODE, READONLY + PRESERVE8 +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_timer_interrupt SMP/Cortex-R8/ARM */ +/* 6.2.0 */ +/* AUTHOR */ +/* */ +/* Scott Larson, 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_time_slice Time slice interrupted thread */ +/* _tx_thread_smp_protect Get SMP protection */ +/* _tx_thread_smp_unprotect Releast SMP protection */ +/* _tx_timer_expiration_process Timer expiration processing */ +/* */ +/* CALLED BY */ +/* */ +/* interrupt vector */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 10-31-2022 Scott Larson Initial Version 6.2.0 */ +/* */ +/**************************************************************************/ +// VOID _tx_timer_interrupt(VOID) +// { + EXPORT _tx_timer_interrupt +_tx_timer_interrupt + + /* Upon entry to this routine, it is assumed that context save has already + been called, and therefore the compiler scratch registers are available + for use. */ + + MRC p15, 0, r0, c0, c0, 5 // Read CPU ID register + AND r0, r0, #0x03 // Mask off, leaving the CPU ID field + CMP r0, #0 // Only process timer interrupts from core 0 (to change this simply change the constant!) + BEQ __tx_process_timer // If the same process the interrupt + BX lr // Return to caller if not matched +__tx_process_timer + + STMDB sp!, {lr, r4} // Save the lr and r4 register on the stack + BL _tx_thread_smp_protect // Get protection + MOV r4, r0 // Save the return value in preserved register + + LDR r1, =_tx_timer_interrupt_active // Pickup address of timer interrupt active count + LDR r0, [r1, #0] // Pickup interrupt active count + ADD r0, r0, #1 // Increment interrupt active count + STR r0, [r1, #0] // Store new interrupt active count + DMB // Ensure that accesses to shared resource have completed + + /* Increment the system clock. */ + // _tx_timer_system_clock++; + + LDR r1, =_tx_timer_system_clock // Pickup address of system clock + LDR r0, [r1, #0] // Pickup system clock + ADD r0, r0, #1 // Increment system clock + STR r0, [r1, #0] // Store new system clock + + /* Test for timer expiration. */ + // if (*_tx_timer_current_ptr) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CMP r0, #0 // Check for previous timer expiration still active + BNE __tx_timer_done // If so, skip timer processing + LDR r1, =_tx_timer_current_ptr // Pickup current timer pointer addr + LDR r0, [r1, #0] // Pickup current timer + LDR r2, [r0, #0] // Pickup timer list entry + CMP r2, #0 // Is there anything in the list? + BEQ __tx_timer_no_timer // No, just increment the timer + + /* Set expiration flag. */ + // _tx_timer_expired = TX_TRUE; + + LDR r3, =_tx_timer_expired // Pickup expiration flag address + MOV r2, #1 // Build expired value + STR r2, [r3, #0] // Set expired flag + B __tx_timer_done // Finished timer processing + + // } + // else + // { +__tx_timer_no_timer + + /* No timer expired, increment the timer pointer. */ + // _tx_timer_current_ptr++; + + ADD r0, r0, #4 // Move to next timer + + /* Check for wrap-around. */ + // if (_tx_timer_current_ptr == _tx_timer_list_end) + + LDR r3, =_tx_timer_list_end // Pickup addr of timer list end + LDR r2, [r3, #0] // Pickup list end + CMP r0, r2 // Are we at list end? + BNE __tx_timer_skip_wrap // No, skip wrap-around logic + + /* Wrap to beginning of list. */ + // _tx_timer_current_ptr = _tx_timer_list_start; + + LDR r3, =_tx_timer_list_start // Pickup addr of timer list start + LDR r0, [r3, #0] // Set current pointer to list start + +__tx_timer_skip_wrap + + STR r0, [r1, #0] // Store new current timer pointer + // } + +__tx_timer_done + + /* Did a timer expire? */ + // if (_tx_timer_expired) + // { + + LDR r1, =_tx_timer_expired // Pickup addr of expired flag + LDR r0, [r1, #0] // Pickup timer expired flag + CMP r0, #0 // Check for timer expiration + BEQ __tx_timer_dont_activate // If not set, skip timer activation + + /* Process timer expiration. */ + // _tx_timer_expiration_process(); + + BL _tx_timer_expiration_process // Call the timer expiration handling routine + + // } +__tx_timer_dont_activate + + /* Call time-slice processing. */ + // _tx_thread_time_slice(); + + BL _tx_thread_time_slice // Call time-slice processing + + // } + + LDR r1, =_tx_timer_interrupt_active // Pickup address of timer interrupt active count + LDR r0, [r1, #0] // Pickup interrupt active count + SUB r0, r0, #1 // Decrement interrupt active count + STR r0, [r1, #0] // Store new interrupt active count + DMB // Ensure that accesses to shared resource have completed + + /* Release protection. */ + + MOV r0, r4 // Pass the previous status register back + BL _tx_thread_smp_unprotect // Release protection + + LDMIA sp!, {lr, r4} // Recover lr register and r4 + IF {INTER} = {TRUE} + BX lr // Return to caller + ELSE + MOV pc, lr // Return to caller + ENDIF + +// } + END diff --git a/utility/rtos_compatibility_layers/FreeRTOS/config_template/FreeRTOSConfig.h b/utility/rtos_compatibility_layers/FreeRTOS/config_template/FreeRTOSConfig.h index 3afd6982e..28dbb6593 100644 --- a/utility/rtos_compatibility_layers/FreeRTOS/config_template/FreeRTOSConfig.h +++ b/utility/rtos_compatibility_layers/FreeRTOS/config_template/FreeRTOSConfig.h @@ -22,7 +22,10 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* 09-30-2020 William E. Lamie Initial Version 6.1 */ +/* 10-31-2022 Scott Larson Change configSTACK_DEPTH_TYPE */ +/* to 32 bit instead of 16 bit, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -52,7 +55,7 @@ /* #define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 */ /* #define configMESSAGE_BUFFER_LENGTH_TYPE size_t */ -#define configSTACK_DEPTH_TYPE uint16_t +#define configSTACK_DEPTH_TYPE uint32_t /* #define configUSE_CO_ROUTINES 0 */ /* #define configMAX_CO_ROUTINE_PRIORITIES (2) */ diff --git a/utility/rtos_compatibility_layers/posix/px_int.h b/utility/rtos_compatibility_layers/posix/px_int.h index c907d312c..9c10a60fe 100644 --- a/utility/rtos_compatibility_layers/posix/px_int.h +++ b/utility/rtos_compatibility_layers/posix/px_int.h @@ -24,7 +24,7 @@ /* EKP DEFINITIONS RELEASE */ /* */ /* px_int.h PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -39,7 +39,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Remove unneeded values, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -52,14 +54,9 @@ #define TX_INITIALIZE_IN_PROGRESS 0xF0F0F0F0UL #define TX_INITIALIZE_ALMOST_DONE 0xF0F0F0F1UL -/* Include necessary definition for memory related routines(from tx_byt.c). */ -#define TX_BYTE_BLOCK_FREE 0xFFFFEEEEUL -#define TX_BYTE_BLOCK_ALLOC 0xAAAAAAAAUL -#define TX_BYTE_POOL_ID 0x42595445UL - /* Threadx min and max priority */ #define TX_HIGHEST_PRIORITY 1 -#define TX_LOWEST_PRIORITY 31 +#define TX_LOWEST_PRIORITY 31 #define PX_HIGHEST_PRIORITY 31 #define PX_LOWEST_PRIORITY 1 @@ -194,7 +191,7 @@ VOID posix_thread_wrapper(ULONG pthr_ptr); VOID set_default_pthread_attr(pthread_attr_t *attr); -VOID set_default_mutexattr(pthread_mutexattr_t *attr); +VOID set_default_mutexattr(pthread_mutexattr_t *attr); INT posix_allocate_pthread_t(POSIX_TCB **ptcb_ptr); diff --git a/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c b/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c index 6bddee435..2a3a3131b 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_arrange_msg.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** POSIX wrapper for THREADX */ +/** */ +/** POSIX wrapper for THREADX */ /** */ /** */ /** */ @@ -32,14 +32,14 @@ /* FUNCTION RELEASE */ /* */ /* posix_arrange_msg PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ -/* arrange messages from the queue */ +/* Return the oldest, highest priority message from the queue. */ /* */ /* INPUT */ /* */ @@ -62,117 +62,128 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Modified comments, */ +/* fixed message swap logic, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ -ULONG posix_arrange_msg( TX_QUEUE *Queue, ULONG *pMsgPrio ) +ULONG posix_arrange_msg(TX_QUEUE *Queue, ULONG *pMsgPrio) { - - ULONG* Qread; /* to store read ptr of the queue */ - ULONG* temp_q = TX_NULL; /* temp storage for the message pointer */ - ULONG numMsgs; /* no of messages queued */ - ULONG msg; /* temp variable for thr for loop */ - ULONG priority; /* priority of the message */ - ULONG maxPrio; /* max. priority of the messages in queue*/ - ULONG number2; /* messages */ - ULONG minNo; /* oldest message in the same priority */ - ULONG swap; /* temp.variable for the swapping of the */ - /* messages */ + ULONG* q_read; /* to store read ptr of the queue */ + ULONG* temp_q = TX_NULL; /* temp storage for the message pointer */ + ULONG numMsgs; /* no of messages queued */ + ULONG msg; /* temp variable for thr for loop */ + ULONG priority; /* priority of the message */ + ULONG maxPrio; /* max. priority of the messages in queue*/ + ULONG number2; /* messages */ + ULONG minNo; /* oldest message in the same priority */ + ULONG swap; /* temp.variable for the swapping of the */ + /* messages */ /* initialize the priority to the lowest priority. */ maxPrio = 0; - minNo=0; + minNo = 0; /* Copy read pointer to the temporary variable. */ - Qread = Queue -> tx_queue_read; + q_read = Queue -> tx_queue_read; /* Copy no. of messages in the queue to the temporary variable. */ numMsgs = Queue -> tx_queue_enqueued; - if( numMsgs == 0 ) + /* If there is 0 or 1 message, no rearranging is needed. */ + if (numMsgs < 2) + { return(OK); + } - for( msg = 0; msg < numMsgs; msg ++) + for (msg = 0; msg < numMsgs; msg++) { - - /* Advance Qread by two pointers to read the priority of the message. */ - Qread = Qread + 2 ; + /* Advance q_read to read the priority of the message. */ + q_read = q_read + TX_POSIX_QUEUE_PRIORITY_OFFSET; /* Priority of the message queued. */ - priority = *Qread; + priority = *q_read; /* check with maxpriority. */ - if( priority > maxPrio ) - { - /* copy read pointer to temporary buffer. */ - temp_q = Qread-2; + if (priority > maxPrio) + { + /* copy read pointer to temporary pointer. */ + temp_q = q_read-TX_POSIX_QUEUE_PRIORITY_OFFSET; + /* increment read pointer to point to order. */ - Qread++; + q_read++; /* copy FIFO order to the message */ - minNo = *Qread; + minNo = *q_read; + /* Found higher priority message. */ maxPrio = priority; - Qread++; + q_read++; } - - /* if more than one same priority messages are in the queue - then check if this the oldest one. */ - else if ( priority == maxPrio ) + + /* if more than one message of the same priority is in the queue + then check if this the oldest message. */ + else if (priority == maxPrio) { /* increment read pointer to point to read FIFO order */ - Qread++; - - /* copy number to the local varialble. */ - number2 = *Qread; - Qread++; - /* find the oldest of the messages in this priority level. */ - if( number2 < minNo ) - { - /* founder older one */ - minNo = number2; - /* copy read pointer to temporary buffer. */ - temp_q = Qread - 4; - } - + q_read++; + + /* copy number to the local variable. */ + number2 = *q_read; + + /* Go to next message. */ + q_read++; + + /* find the oldest of the messages in this priority level. */ + if( number2 < minNo ) + { + /* founder older one */ + minNo = number2; + /* copy read pointer to temporary buffer. */ + temp_q = q_read - (TX_POSIX_MESSAGE_SIZE); + } } - else - Qread = Qread + 2; - - /* Determine if we are at the end. */ - if ( Qread >= Queue ->tx_queue_end) + else + { + /* Not highest priority, go to next message. */ + q_read = q_read + (TX_POSIX_MESSAGE_SIZE - TX_POSIX_QUEUE_PRIORITY_OFFSET); + } - /* Yes, wrap around to the beginning. */ - Qread = Queue -> tx_queue_start; + /* Determine if we are at the end. */ + if (q_read >= Queue -> tx_queue_end) + { + /* Yes, wrap around to the beginning. */ + q_read = Queue -> tx_queue_start; + } } - /* All messages checked temp holds address of highest priority message and - maxPrio holds the highest priority*/ - - if( pMsgPrio != NULL ) + /* Output priority if non-null */ + if (pMsgPrio != NULL) { /* copy message priority. */ *pMsgPrio = maxPrio; } + /* All messages checked, temp_q holds address of oldest highest priority message + and maxPrio holds the highest priority. */ /* Get the current queue read pointer */ - Qread = Queue -> tx_queue_read; - - /* if(*pMsgPrio != *(Qread + 2) || minNo < *(Qread + 3))*/ + q_read = Queue -> tx_queue_read; + + if((temp_q != TX_NULL) && (temp_q != q_read)) { /* Swap the messages. */ - for ( msg = 0; msg < 4; msg++) + for (msg = 0; msg < TX_POSIX_MESSAGE_SIZE; msg++) { - swap = *temp_q; - *temp_q = *Qread; - *Qread = swap; + *temp_q = *q_read; + *q_read = swap; temp_q++; - Qread++; + q_read++; } } - + return(OK); } diff --git a/utility/rtos_compatibility_layers/posix/px_mq_create.c b/utility/rtos_compatibility_layers/posix/px_mq_create.c index 19a559213..e52cefa56 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_create.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_create.c @@ -26,13 +26,12 @@ #include "pthread.h" /* Posix API */ #include "px_int.h" /* Posix helper functions */ - /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* posix_mq_create PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -74,7 +73,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ POSIX_MSG_QUEUE * posix_mq_create (const CHAR * mq_name, @@ -125,9 +126,9 @@ TX_QUEUE *TheQ; to store only the message pointer and message length. */ temp1 = tx_queue_create((&(posix_q->queue)), (CHAR *)mq_name, - TX_4_ULONG, + TX_POSIX_MESSAGE_SIZE, posix_q->storage, - (msgq_attr->mq_maxmsg * 16)); + (msgq_attr->mq_maxmsg * (sizeof(ULONG) * TX_POSIX_MESSAGE_SIZE))); /* Make sure it worked. */ if (temp1 != TX_SUCCESS) diff --git a/utility/rtos_compatibility_layers/posix/px_mq_open.c b/utility/rtos_compatibility_layers/posix/px_mq_open.c index b88c465d4..bb041e090 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_open.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_open.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* mq_open PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -68,7 +68,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Update comparison with NULL, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ mqd_t mq_open(const CHAR * mqName, ULONG oflags,...) @@ -115,7 +117,7 @@ ULONG temp1; } /* Check if name is exist. NULL if successful. */ - if(posix_queue = posix_find_queue(mqName)) + if((posix_queue = posix_find_queue(mqName)) != NULL) { if(posix_queue->unlink_flag == TX_TRUE) { @@ -172,7 +174,7 @@ ULONG temp1; case O_RDWR: case O_NONBLOCK: /* Check if name is exist. NULL if successful. */ - if(posix_queue = posix_find_queue(mqName)) + if((posix_queue = posix_find_queue(mqName)) != NULL) { if(posix_queue->unlink_flag == TX_TRUE) { diff --git a/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c b/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c index 5846c94e9..07444666d 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_priority_search.c @@ -12,8 +12,8 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** POSIX wrapper for THREADX */ +/** */ +/** POSIX wrapper for THREADX */ /** */ /** */ /** */ @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* posix_priority_search PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -63,15 +63,17 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ -ULONG posix_priority_search(mqd_t msgQId ,ULONG priority) +ULONG posix_priority_search(mqd_t msgQId, ULONG priority) { TX_QUEUE *queue; POSIX_MSG_QUEUE *q_ptr; -ULONG order; +ULONG order = 1; ULONG numMsgs; UINT index; ULONG *source; @@ -87,18 +89,21 @@ ULONG msgp; source = q_ptr->queue.tx_queue_read; /* check for same priority. */ - for(index = 0,order = 1;index <= numMsgs ;index++) + for(index = 0; index < numMsgs; index++) { - source += 2; + source += TX_POSIX_QUEUE_PRIORITY_OFFSET; msgp = *source; - source += 2; + source += (TX_POSIX_MESSAGE_SIZE - TX_POSIX_QUEUE_PRIORITY_OFFSET); + /* If we're at end of queue, go to start. */ if(source == q_ptr->queue.tx_queue_end) source = q_ptr->queue.tx_queue_start; - + + /* Increment priority count. */ if(priority == msgp) order += 1; } - /* Returns the number of same priority messages. */ + + /* Return the number of same priority messages. */ return(order); } diff --git a/utility/rtos_compatibility_layers/posix/px_mq_receive.c b/utility/rtos_compatibility_layers/posix/px_mq_receive.c index 693017d1e..f012e187f 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_receive.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_receive.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* mq_receive PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -71,7 +71,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ ssize_t mq_receive( mqd_t mqdes, VOID * pMsg, size_t msgLen, ULONG *pMsgPrio) @@ -141,7 +143,7 @@ VOID * message_source; /* Try to get a message from the message queue. */ /* Create a temporary buffer to get message pointer and message length. */ - temp1 = posix_memory_allocate((sizeof(ULONG)) * 4 , (VOID**)&msgbuf1); + temp1 = posix_memory_allocate((sizeof(ULONG)) * TX_POSIX_MESSAGE_SIZE, (VOID**)&msgbuf1); if(temp1 != TX_SUCCESS ) { /* Return generic error. */ @@ -212,11 +214,18 @@ VOID * message_source; my_ptr = ( ULONG *)msgbuf1; /* Retrieve Message pointer, message Length and message priority. */ +#ifdef TX_64_BIT + this_ptr = (CHAR *)((((ALIGN_TYPE)my_ptr[0]) << 32) | my_ptr[1]); + length_of_message = my_ptr[2]; + priority_of_message = my_ptr[3]; +#else this_ptr = (CHAR *)(*my_ptr); - message_source = (VOID *)this_ptr; length_of_message = *(++my_ptr); priority_of_message = *(++my_ptr); +#endif + message_source = (VOID *)this_ptr; + /* Copy message into supplied buffer. */ msgbuf2 = (UCHAR *)pMsg; diff --git a/utility/rtos_compatibility_layers/posix/px_mq_send.c b/utility/rtos_compatibility_layers/posix/px_mq_send.c index da566db61..f8cacc094 100644 --- a/utility/rtos_compatibility_layers/posix/px_mq_send.c +++ b/utility/rtos_compatibility_layers/posix/px_mq_send.c @@ -26,7 +26,6 @@ #include "pthread.h" /* Posix API */ #include "px_int.h" /* Posix helper functions */ - /**************************************************************************/ /* */ /* FUNCTION RELEASE */ @@ -73,7 +72,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ INT mq_send( mqd_t mqdes, const CHAR * msg_ptr, size_t msg_len, @@ -88,7 +89,7 @@ UCHAR *source; UCHAR *destination; UCHAR *save_ptr; ULONG mycount; -ULONG msg[4]; +ULONG msg[TX_POSIX_MESSAGE_SIZE]; /* Assign a temporary variable for clarity. */ Queue = &(mqdes->f_data->queue); @@ -99,7 +100,7 @@ ULONG msg[4]; { /* Queue pointer is invalid, return appropriate error code. */ posix_errno = EBADF; - posix_set_pthread_errno(EBADF); + posix_set_pthread_errno(EBADF); /* Return ERROR. */ return(ERROR); @@ -110,7 +111,7 @@ ULONG msg[4]; { /* POSIX doesn't have error for this, hence give default. */ posix_errno = EINTR ; - posix_set_pthread_errno(EINTR); + posix_set_pthread_errno(EINTR); /* Return ERROR. */ return(ERROR); @@ -121,7 +122,7 @@ ULONG msg[4]; { /* Queue descriptor is invalid, set appropriate error code. */ posix_errno = EBADF ; - posix_set_pthread_errno(EBADF); + posix_set_pthread_errno(EBADF); /* Return ERROR. */ return(ERROR); @@ -130,7 +131,7 @@ ULONG msg[4]; { /* Queue pointer is invalid, return appropriate error code. */ posix_errno = EBADF; - posix_set_pthread_errno(EBADF); + posix_set_pthread_errno(EBADF); /* Return ERROR. */ return(ERROR); @@ -139,7 +140,7 @@ ULONG msg[4]; { /* Return appropriate error. */ posix_errno = EINVAL; - posix_set_pthread_errno(EINVAL); + posix_set_pthread_errno(EINVAL); /* Return error. */ return(ERROR); @@ -149,7 +150,7 @@ ULONG msg[4]; { /* POSIX doesn't have error for this, hence give default. */ posix_errno = EINTR ; - posix_set_pthread_errno(EINTR); + posix_set_pthread_errno(EINTR); /* Return ERROR. */ return(ERROR); @@ -160,7 +161,7 @@ ULONG msg[4]; { /* Return message length exceeds max length. */ posix_errno = EMSGSIZE ; - posix_set_pthread_errno(EMSGSIZE); + posix_set_pthread_errno(EMSGSIZE); /* Return ERROR. */ return(ERROR); @@ -192,11 +193,18 @@ ULONG msg[4]; /* Restore the pointer of save message. */ source = save_ptr ; /* Create message that holds saved message pointer and message length. */ +#ifdef TX_64_BIT + msg[0] = (ULONG)((ALIGN_TYPE)source >> 32); + msg[1] = (ULONG)((ALIGN_TYPE)source); + msg[2] = msg_len; + msg[3] = msg_prio; + msg[4] = posix_priority_search(mqdes, msg_prio); +#else msg[0] = (ULONG)source; msg[1] = msg_len; msg[2] = msg_prio; msg[3] = posix_priority_search(mqdes, msg_prio); - +#endif /* Attempt to post the message to the queue. */ temp1 = tx_queue_send(Queue, msg, TX_WAIT_FOREVER); if ( temp1 != TX_SUCCESS) diff --git a/utility/rtos_compatibility_layers/posix/px_nanosleep.c b/utility/rtos_compatibility_layers/posix/px_nanosleep.c index 45f6b0407..c9e21cd31 100644 --- a/utility/rtos_compatibility_layers/posix/px_nanosleep.c +++ b/utility/rtos_compatibility_layers/posix/px_nanosleep.c @@ -12,40 +12,38 @@ /**************************************************************************/ /**************************************************************************/ -/** */ -/** POSIX wrapper for THREADX */ -/** */ /** */ +/** POSIX wrapper for THREADX */ /** */ /**************************************************************************/ /**************************************************************************/ /* Include necessary system files. */ -#include "tx_api.h" /* Threadx API */ -#include "pthread.h" /* Posix API */ -#include "px_int.h" /* Posix helper functions */ - +#include "tx_api.h" /* Threadx API */ +#include "pthread.h" /* Posix API */ +#include "px_int.h" /* Posix helper functions */ +#include -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* nanosleep PORTABLE C */ -/* 6.1.7 */ +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* nanosleep PORTABLE C */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ /* */ -/* DESCRIPTION */ +/* DESCRIPTION */ /* */ /* This function shall cause the current thread to be suspended from */ /* execution until the time interval specified by the req argument has */ -/* elapsed */ +/* elapsed. */ /* */ -/* INPUT */ +/* INPUT */ /* */ -/* req Is the number of real-time (as opposed */ +/* req The number of real-time (as opposed */ /* to CPU-time) seconds and nanoseconds to */ /* suspend the calling thread. */ /* rem Points to a structure to receive the */ @@ -53,61 +51,62 @@ /* interrupted by a signal. This pointer */ /* may be NULL. */ /* */ -/* OUTPUT */ -/* */ +/* OUTPUT */ +/* */ /* zero If the function returns because the */ /* requested time has elapsed. */ /* */ /* -1 If this functions fails if req argument */ -/* specified a value less than zero or */ -/* greater than or equal to 1 000 million. */ +/* specified a nanosecond value greater */ +/* than or equal to 1 billion. */ /* */ /* */ -/* CALLS */ +/* CALLS */ /* */ /* tx_thread_sleep ThreadX thread sleep service */ /* */ -/* CALLED BY */ -/* */ -/* Application Code */ -/* */ -/* RELEASE HISTORY */ -/* */ +/* CALLED BY */ +/* */ +/* Application Code */ +/* */ +/* RELEASE HISTORY */ +/* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Fix bounds check, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ INT nanosleep(struct timespec *req, struct timespec *rem) { ULONG timer_ticks; - - /* Check for valid inputs */ - /* The nanosecond value must be greater than zero or less than 1 000 million. */ - if ( (!req) || ((req->tv_nsec) <= 0) || (req->tv_nsec > 999999999 )) /* 08-11-2005 */ + /* Check for valid inputs - the nanosecond value must be less than 1 billion + and not roll over when converting to ThreadX timer ticks. */ + if ( (!req) || (req->tv_nsec > 999999999) || ((timer_ticks = (req->tv_sec * CPU_TICKS_PER_SECOND + req->tv_nsec/NANOSECONDS_IN_CPU_TICK)) < req->tv_sec) ) { posix_errno = EINVAL; posix_set_pthread_errno(EINVAL); return(ERROR); } - - /* Convert sleep time into Clock ticks */ - /* Also add some padding so that the thread will sleep no less than the - specified time */ - - timer_ticks = (ULONG) ( ( req->tv_sec * CPU_TICKS_PER_SECOND ) + ( req->tv_nsec/ NANOSECONDS_IN_CPU_TICK) + 1 ); /* 08-11-2005 */ - /* Now call ThreadX thread sleep service */ + /* Add padding of 1 so that the thread will sleep no less than the specified time, + except in the case that timer_ticks is ULONG_MAX */ + if(timer_ticks != ULONG_MAX) + { + timer_ticks = timer_ticks + 1; + } + + /* Now call ThreadX thread sleep service. */ tx_thread_sleep(timer_ticks); - /* Sleep completed */ - if ( rem ) /* 08-11-2005 */ + /* Sleep completed. */ + if (rem) { - rem->tv_nsec = 0; - rem->tv_sec = 0; /* 08-11-2005 */ - } + rem->tv_nsec = 0; + rem->tv_sec = 0; + } return(OK); - } diff --git a/utility/rtos_compatibility_layers/posix/px_pth_create.c b/utility/rtos_compatibility_layers/posix/px_pth_create.c index 511026dbe..60b79f845 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_create.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_create.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* pthread_create PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -98,7 +98,10 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* remove double parenthesis, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ INT pthread_create (pthread_t *thread, pthread_attr_t *attr, @@ -211,7 +214,7 @@ INT status,retval; status = posix_memory_allocate( pthread_ptr->stack_size, &(pthread_ptr->stack_address)); /* problem allocating stack space */ - if ((status == ERROR)) + if (status == ERROR) { /* Configuration/resource error. */ return(EAGAIN); @@ -227,17 +230,19 @@ INT status,retval; /* Now actually create and start the thread. */ /* convert Posix priorities to Threadx priority */ - retval += tx_thread_create( thread_ptr, + retval += tx_thread_create(thread_ptr, "pthr", posix_thread_wrapper, - (ULONG)pthread_ptr, + (ULONG)(ALIGN_TYPE)pthread_ptr, pthread_ptr->stack_address, pthread_ptr->stack_size, (TX_LOWEST_PRIORITY - pthread_ptr->current_priority + 1), (TX_LOWEST_PRIORITY - pthread_ptr->threshold + 1), pthread_ptr->time_slice, TX_AUTO_START); - + + TX_THREAD_EXTENSION_PTR_SET(thread_ptr, pthread_ptr) + /* See if ThreadX encountered an error */ if (retval) { diff --git a/utility/rtos_compatibility_layers/posix/px_pth_init.c b/utility/rtos_compatibility_layers/posix/px_pth_init.c index d0e54606d..1225692c8 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_init.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_init.c @@ -318,7 +318,7 @@ ULONG index; /* FUNCTION RELEASE */ /* */ /* posix_thread_wrapper PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -352,7 +352,9 @@ ULONG index; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ VOID posix_thread_wrapper(ULONG pthr_ptr) @@ -362,7 +364,8 @@ POSIX_TCB *pthread_ptr; VOID *value_ptr; /* The input argument is really a pointer to the pthread's control block */ - pthread_ptr = (POSIX_TCB *) pthr_ptr; + TX_THREAD_EXTENSION_PTR_GET(pthread_ptr, POSIX_TCB, pthr_ptr) + /* Invoke the pthread start routine with appropriate arguments */ value_ptr = (pthread_ptr->start_routine)((VOID *)pthread_ptr->entry_parameter); @@ -668,7 +671,7 @@ POSIX_TCB *pthread; /* FUNCTION RELEASE */ /* */ /* posix_destroy_pthread PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -701,19 +704,28 @@ POSIX_TCB *pthread; /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ VOID posix_destroy_pthread(POSIX_TCB *pthread_ptr, VOID *value_ptr) { -ULONG request[WORK_REQ_SIZE]; -INT status; +ULONG request[WORK_REQ_SIZE]; +UINT status; /* Build the request. */ - - request[0] = (ULONG)pthread_ptr; + +#ifdef TX_64_BIT + request[0] = (ULONG)((ALIGN_TYPE)pthread_ptr >> 32); + request[1] = (ULONG)((ALIGN_TYPE)pthread_ptr); + request[2] = (ULONG)((ALIGN_TYPE)value_ptr >> 32); + request[3] = (ULONG)((ALIGN_TYPE)value_ptr); +#else + request[0] = (ULONG)pthread_ptr; request[1] = (ULONG)value_ptr; +#endif /* Send a message to the SysMgr supervisor thread, asking it to delete */ /* the pthread. Since the SysMgr supervisor thread is the highest */ diff --git a/utility/rtos_compatibility_layers/posix/px_pth_kill.c b/utility/rtos_compatibility_layers/posix/px_pth_kill.c index dacdbba01..f84bceb20 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_kill.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_kill.c @@ -33,7 +33,7 @@ /* FUNCTION RELEASE */ /* */ /* pthread_kill PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -73,11 +73,13 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Remove double parenthesis, */ +/* update argument type, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ - -int pthread_kill(ULONG thread_id, int sig) +int pthread_kill(ALIGN_TYPE thread_id, int sig) { TX_INTERRUPT_SAVE_AREA @@ -197,7 +199,7 @@ UINT retval; status = posix_memory_allocate(new_signal_thread -> stack_size, &new_signal_thread -> stack_address); /* problem allocating stack space */ - if ((status == ERROR)) + if (status == ERROR) { /* Mark the previously allocated control block as available. */ diff --git a/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c b/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c index e2dab6861..fa9d1f795 100644 --- a/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c +++ b/utility/rtos_compatibility_layers/posix/px_pth_sigmask.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* pthread_sigmask PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -68,7 +68,10 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Update pthread_kill argument */ +/* cast, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -188,7 +191,7 @@ ULONG reissue_flag; base_thread -> signals.signal_pending.signal_set = base_thread -> signals.signal_pending.signal_set & ~(((unsigned long) 1) << signal_number); /* Call pthread_kill to reissue the signal. */ - pthread_kill((ULONG) base_thread, signal_number); + pthread_kill((ALIGN_TYPE) base_thread, signal_number); /* Set the reissue flag. */ reissue_flag = TX_TRUE; diff --git a/utility/rtos_compatibility_layers/posix/px_sem_open.c b/utility/rtos_compatibility_layers/posix/px_sem_open.c index 72b920271..ca97c4e8e 100644 --- a/utility/rtos_compatibility_layers/posix/px_sem_open.c +++ b/utility/rtos_compatibility_layers/posix/px_sem_open.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* sem_open PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -69,7 +69,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Update comparison with NULL, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ sem_t * sem_open(const CHAR * name, ULONG oflag, ...) @@ -110,7 +112,7 @@ mode_t mode; } /* Check if semaphore exists. */ - if(semid= posix_find_sem( name)) + if((semid = posix_find_sem(name)) != NULL) { if(semid->unlink_flag ==TX_TRUE ) { diff --git a/utility/rtos_compatibility_layers/posix/px_sem_unlink.c b/utility/rtos_compatibility_layers/posix/px_sem_unlink.c index 2d7c1e694..564bb2240 100644 --- a/utility/rtos_compatibility_layers/posix/px_sem_unlink.c +++ b/utility/rtos_compatibility_layers/posix/px_sem_unlink.c @@ -32,7 +32,7 @@ /* FUNCTION RELEASE */ /* */ /* sem_unlink PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -65,7 +65,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Remove double parenthesis, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ INT sem_unlink(const CHAR * name) @@ -102,7 +104,7 @@ ULONG len; sem->unlink_flag =TX_TRUE; /* Check for the count. */ - if ((sem->count == 0) ) + if(sem->count == 0) { posix_sem_reset(sem ); sem = NULL; diff --git a/utility/rtos_compatibility_layers/posix/px_system_manager.c b/utility/rtos_compatibility_layers/posix/px_system_manager.c index 8204b4e3d..0e6c6a323 100644 --- a/utility/rtos_compatibility_layers/posix/px_system_manager.c +++ b/utility/rtos_compatibility_layers/posix/px_system_manager.c @@ -31,7 +31,7 @@ /* FUNCTION RELEASE */ /* */ /* posix_system_manager_entry PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -63,7 +63,9 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Add 64-bit support, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ VOID posix_system_manager_entry(ULONG input) @@ -72,25 +74,35 @@ VOID posix_system_manager_entry(ULONG input) UINT status; ULONG request[WORK_REQ_SIZE]; - - /* Avoid compiler warning. */ - if (input) { } +POSIX_TCB *pthread_ptr; +VOID *value_ptr; + + /* Avoid compiler warning. */ + TX_PARAMETER_NOT_USED(input); /* Loop forever, waiting for work requests. */ while(1) { - /* Wait forever for the next work request. */ + /* Wait forever for the next work request. */ status = tx_queue_receive(&posix_work_queue, &request, TX_WAIT_FOREVER); /* Make sure we didn't encounter any trouble. */ if (status != TX_SUCCESS) { - /* Hmmmm... should not happen. */ - /* Anywayjust go back and get the next message. */ - continue; + /* Get the next message. */ + continue; } - /* Go delete the pthread */ - posix_do_pthread_delete((POSIX_TCB *)request[0], (VOID *)request[1] ); - } /* System Manager forever loop */ + #ifdef TX_64_BIT + pthread_ptr = (POSIX_TCB *)((((ALIGN_TYPE)request[0]) << 32) | request[1]); + value_ptr = (VOID *)((((ALIGN_TYPE)request[2]) << 32) | request[3]); + #else + pthread_ptr = (POSIX_TCB *)request[0]; + value_ptr = (VOID *)request[1]; + #endif + + /* Delete the pthread */ + posix_do_pthread_delete(pthread_ptr, value_ptr); + + } /* System Manager forever loop */ } diff --git a/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt b/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt index 82977a8c3..5aeb5d529 100644 --- a/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt +++ b/utility/rtos_compatibility_layers/posix/readme_threadx_posix.txt @@ -173,7 +173,7 @@ INT sched_get_priority_min(INT policy) INT pthread_once (pthread_once_t * once_control, VOID (*init_routine) (VOID)) -INT pthread_kill(ULONG thread_id, int sig) +INT pthread_kill(ALIGN_TYPE thread_id, int sig) INT pthread_sigmask(int how, const sigset_t *newmask, sigset_t *oldmask) diff --git a/utility/rtos_compatibility_layers/posix/signal.h b/utility/rtos_compatibility_layers/posix/signal.h index 156c88d9d..586576846 100644 --- a/utility/rtos_compatibility_layers/posix/signal.h +++ b/utility/rtos_compatibility_layers/posix/signal.h @@ -24,7 +24,7 @@ /* EKP DEFINITIONS RELEASE */ /* */ /* signal.h PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -39,7 +39,10 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Update pthread_kill argument */ +/* type, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -100,7 +103,7 @@ typedef struct signal_info_struct /* Define public POSIX routines. */ int signal(int signo, void (*func)(int)); -int pthread_kill(ULONG thread, int sig); +int pthread_kill(ALIGN_TYPE thread, int sig); int sigwait(const sigset_t *set, int *sig); int sigemptyset(sigset_t *set); int sigaddset(sigset_t *set, int signo); diff --git a/utility/rtos_compatibility_layers/posix/tx_posix.h b/utility/rtos_compatibility_layers/posix/tx_posix.h index e6f8406c9..db85e00ba 100644 --- a/utility/rtos_compatibility_layers/posix/tx_posix.h +++ b/utility/rtos_compatibility_layers/posix/tx_posix.h @@ -24,7 +24,7 @@ /* EKP DEFINITIONS RELEASE */ /* */ /* tx_posix.h PORTABLE C */ -/* 6.1.7 */ +/* 6.2.0 */ /* AUTHOR */ /* */ /* William E. Lamie, Microsoft Corporation */ @@ -39,7 +39,10 @@ /* */ /* DATE NAME DESCRIPTION */ /* */ -/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 06-02-2021 William E. Lamie Initial Version 6.1.7 */ +/* 10-31-2022 Scott Larson Update WORK_REQ_SIZE value, */ +/* update pthread_t typedef, */ +/* resulting in version 6.2.0 */ /* */ /**************************************************************************/ @@ -65,6 +68,13 @@ #define MQ_FLAGS 0 #define MQ_PRIO_MAX 32 /* Maximum priority of message. */ +#ifdef TX_64_BIT +#define TX_POSIX_MESSAGE_SIZE 5 +#define TX_POSIX_QUEUE_PRIORITY_OFFSET 3 +#else +#define TX_POSIX_MESSAGE_SIZE 4 +#define TX_POSIX_QUEUE_PRIORITY_OFFSET 2 +#endif /************************************************************************/ /* Global Variables */ /************************************************************************/ @@ -254,7 +264,7 @@ typedef ULONG BOOL; /* these constants control internal working of the systemmanager thread */ -#define WORK_REQ_SIZE TX_2_ULONG +#define WORK_REQ_SIZE (TX_2_ULONG * (sizeof(ALIGN_TYPE)/sizeof(ULONG))) #define WORK_QUEUE_DEPTH 10 #define SYSMGR_PRIORITY 0 @@ -279,7 +289,7 @@ typedef struct pthread_attr_obj typedef INT ssize_t ; /* this should be pulled in from sys\types.h */ -typedef ULONG pthread_t; +typedef ALIGN_TYPE pthread_t; typedef ULONG mode_t;