diff --git a/.github/.cSpellWords.txt b/.github/.cSpellWords.txt index 3582741e3..f36fdc816 100644 --- a/.github/.cSpellWords.txt +++ b/.github/.cSpellWords.txt @@ -23,6 +23,7 @@ AIRCR ALMIEN ALMV ANDC +andi ANDCCR APIC APROCFREQ @@ -47,6 +48,7 @@ bcpc BCPC beevt BEEVT +beqz BERR bfextu Biagioni @@ -298,6 +300,7 @@ FADD FCMD fcolor FCSE +fcsr fdiagnostics fdiv FDIV @@ -783,6 +786,7 @@ SHPR SHTIM SIFIVE sinclude +slli SODR SOFTIRQ SPCK @@ -934,6 +938,7 @@ USRIO utest utilises utilising +vcsr VDDCORE vect Vect @@ -944,6 +949,7 @@ visualisation vldmdbeq vldmia vldmiaeq +vlenb VMSRNE vpop VPOPNE @@ -951,6 +957,7 @@ vpush VPUSHNE VRPM Vrtc +vsetvl vstmdbeq vstmiaeq VTOR diff --git a/.github/scripts/kernel_checker.py b/.github/scripts/kernel_checker.py index 228257042..3e770fed4 100755 --- a/.github/scripts/kernel_checker.py +++ b/.github/scripts/kernel_checker.py @@ -114,6 +114,10 @@ KERNEL_ARM_COLLAB_FILES_PATTERNS = [ r'.*portable/.*/ARM_CM35*', r'.*portable/.*/ARM_CM55*', r'.*portable/.*/ARM_CM85*', + r'.*portable/.*/ARM_CM0*', + r'.*portable/.*/ARM_CM3_MPU*', + r'.*portable/.*/ARM_CM4_MPU*', + r'.*portable/.*/ARM_CM4F_MPU*', ] KERNEL_HEADER = [ @@ -150,8 +154,8 @@ KERNEL_HEADER = [ FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$" FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX = r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$)|" + \ - r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d Arm Limited and/or its affiliates( \*\/)?$)|" + \ - r"(^(;|#)?( *(\/\*|\*|#|\/\/))? ( \*\/)?$)" + r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d(-20\d\d)? Arm Limited and/or its affiliates( +)?( \*\/)?$)|" + \ + r"(^(;|#)?( *(\/\*|\*|#|\/\/))? ( \*\/)?$)" class KernelHeaderChecker(HeaderChecker): diff --git a/.github/workflows/auto-release.yml b/.github/workflows/auto-release.yml index 3477f6591..2cd6fde6e 100644 --- a/.github/workflows/auto-release.yml +++ b/.github/workflows/auto-release.yml @@ -18,6 +18,8 @@ on: jobs: release-packager: + permissions: + id-token: write name: Release Packager runs-on: ubuntu-latest steps: @@ -117,6 +119,14 @@ jobs: ./tools/.github/scripts/release.py "$REPO_OWNER" --kernel-repo-path=local_kernel --kernel-commit="$COMMIT_SHA_2" --new-kernel-version="$VERSION_NUMBER" --new-kernel-main-br-version="$MAIN_BR_VERSION_NUMBER" exit $? + - name: Backup Release Asset + uses: FreeRTOS/CI-CD-Github-Actions/artifact-backup@main + with: + # This is dependent on the release script putting this zip file + # in this exact location. + artifact_path: ./FreeRTOS-KernelV${{ github.event.inputs.version_number }}.zip + release_tag: ${{ github.event.inputs.version_number }} + - name: Cleanup env: VERSION_NUMBER: ${{ github.event.inputs.version_number }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index edda39154..2765466be 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,7 +7,7 @@ on: workflow_dispatch: jobs: formatting: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.1.1 - name: Check Formatting of FreeRTOS-Kernel Files diff --git a/.github/workflows/coverity_scan.yml b/.github/workflows/coverity_scan.yml index 803a29ba8..0afc8e2e1 100644 --- a/.github/workflows/coverity_scan.yml +++ b/.github/workflows/coverity_scan.yml @@ -42,11 +42,22 @@ jobs: # ${{ env.stepName }} echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" - wget -nv -qO- https://scan.coverity.com/download/linux64 --post-data "token=${COVERITY_TOKEN}&project=FreeRTOS-Kernel" | tar -zx --one-top-level=cov_scan --strip-components 1 - echo "cov_scan_path=$(pwd)/cov_scan/bin" >> $GITHUB_ENV + wget -nv -q -O "$HOME/cov-analysis.tar.gz" https://scan.coverity.com/download/linux64 --post-data="token=${COVERITY_TOKEN}&project=FreeRTOS-Kernel" + + EXPECTED_MD5="e4418004b073140d67390cffba79c3b2" + GENERATED_MD5=$(md5sum "$HOME/cov-analysis.tar.gz" | awk '{print $1}') - echo "::endgroup::" - echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " + if [ "$GENERATED_MD5" = "$EXPECTED_MD5" ]; then + tar -zxf "$HOME/cov-analysis.tar.gz" --one-top-level=cov_scan -C "$HOME" + echo "cov_scan_path=$HOME/cov_scan/bin" >> $GITHUB_ENV + sudo rm -f "$HOME/cov-analysis.tar.gz" + echo "::endgroup::" + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }} " + else + echo -e "${{ env.bashFail }} MD5 checksum verification failed for cov-analysis.tar.gz ${{ env.bashEnd }}" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit -1 + fi - env: stepName: Coverity Build diff --git a/.github/workflows/formatting.yml b/.github/workflows/formatting.yml deleted file mode 100644 index 2f369105a..000000000 --- a/.github/workflows/formatting.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: Format Pull Request Files - -on: - issue_comment: - types: [created] - -env: - bashPass: \033[32;1mPASSED - - bashInfo: \033[33;1mINFO - - bashFail: \033[31;1mFAILED - - bashEnd: \033[0m - -jobs: - Formatting: - name: Run Formatting Check - if: ${{ github.event.issue.pull_request && - ( ( github.event.comment.body == '/bot run uncrustify' ) || - ( github.event.comment.body == '/bot run formatting' ) ) }} - runs-on: ubuntu-20.04 - steps: - - name: Apply Formatting Fix - id: check-formatting - uses: FreeRTOS/CI-CD-Github-Actions/formatting-bot@main - with: - exclude-dirs: portable diff --git a/.github/workflows/kernel-checks.yml b/.github/workflows/kernel-checks.yml index ad3096f0d..05443458c 100644 --- a/.github/workflows/kernel-checks.yml +++ b/.github/workflows/kernel-checks.yml @@ -5,7 +5,7 @@ on: [push, pull_request] jobs: kernel-checker: name: FreeRTOS Kernel Header Checks - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: # Install python 3 - name: Tool Setup diff --git a/.github/workflows/kernel-demos.yml b/.github/workflows/kernel-demos.yml index 404c602b5..9371e9cea 100644 --- a/.github/workflows/kernel-demos.yml +++ b/.github/workflows/kernel-demos.yml @@ -156,14 +156,27 @@ jobs: run: | # ${{ env.stepName }} echo -e "::group::${{ env.bashInfo }} ${{ env.stepName }} ${{ env.bashEnd }}" - curl -L -O https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-LlCjWuAbzH/9.3.1.2/msp430-gcc-full-linux-x64-installer-9.3.1.2.7z sudo apt update -y sudo apt install -y p7zip-full - 7z x ./msp430-gcc-full-linux-x64-installer-9.3.1.2.7z - chmod +x ./msp430-gcc-full-linux-x64-installer-9.3.1.2.run - sudo ./msp430-gcc-full-linux-x64-installer-9.3.1.2.run --prefix /usr/bin/msp430-gcc --mode unattended - echo "::endgroup::" - echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + pushd $HOME + curl -L -o msp430-gcc-full-linux-x64-installer-9.3.1.2.7z https://dr-download.ti.com/software-development/ide-configuration-compiler-or-debugger/MD-LlCjWuAbzH/9.3.1.2/msp430-gcc-full-linux-x64-installer-9.3.1.2.7z + + EXPECTED_MD5="2db2f99b4cd5c541ca0389ee20c67527" + GENERATED_MD5=$(md5sum msp430-gcc-full-linux-x64-installer-9.3.1.2.7z | awk '{print $1}') + + if [ "$GENERATED_MD5" = "$EXPECTED_MD5" ]; then + 7z x ./msp430-gcc-full-linux-x64-installer-9.3.1.2.7z + chmod +x ./msp430-gcc-full-linux-x64-installer-9.3.1.2.run + sudo ./msp430-gcc-full-linux-x64-installer-9.3.1.2.run --prefix /usr/bin/msp430-gcc --mode unattended + echo "::endgroup::" + popd + echo -e "${{ env.bashPass }} ${{ env.stepName }} ${{ env.bashEnd }}" + else + popd + echo -e "${{ env.bashFail }} MD5 checksum verification failed for msp430-gcc-full-linux-x64-installer-9.3.1.2.7z ${{ env.bashEnd }}" + echo -e "${{ env.bashFail }} ${{ env.stepName }} ${{ env.bashEnd }}" + exit -1 + fi - name: Build msp430_GCC Demo shell: bash @@ -211,21 +224,23 @@ jobs: sudo apt install -y autogen gawk libgmp-dev libmpc-dev libmpfr-dev sudo apt install -y patchutils sharutils zlib1g-dev autoconf2.64 + pushd $HOME # Download the mb-gcc toolchain from github - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/binutils-microblaze_2.35-2021-0623+1_amd64.deb; - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/gcc-microblaze_10.2.0-2021-0623+2_amd64.deb; - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-dev_3.3.0-2021-0623+3_all.deb; - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-doc_3.3.0-2021-0623+3_all.deb; - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze_3.3.0-2021-0623+3_all.deb; - curl -L -O https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/newlib-source_3.3.0-2021-0623+3_all.deb; + curl -L -o binutils-microblaze.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/binutils-microblaze_2.35-2021-0623+1_amd64.deb; + curl -L -o gcc-microblaze.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/gcc-microblaze_10.2.0-2021-0623+2_amd64.deb; + curl -L -o libnewlib-microblaze-dev.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-dev_3.3.0-2021-0623+3_all.deb; + curl -L -o libnewlib-microblaze-doc.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze-doc_3.3.0-2021-0623+3_all.deb; + curl -L -o libnewlib-microblaze.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/libnewlib-microblaze_3.3.0-2021-0623+3_all.deb; + curl -L -o newlib-source.deb https://github.com/mdednev/mb-gcc/releases/download/2021-0623%2B2/newlib-source_3.3.0-2021-0623+3_all.deb; + popd # Install the packages for the toolchain - sudo apt install -y ./binutils-microblaze*.deb; - sudo apt install -y ./gcc-microblaze*.deb; - sudo apt install -y ./libnewlib-microblaze-dev*.deb; - sudo apt install -y ./libnewlib-microblaze-doc*.deb; - sudo apt install -y ./libnewlib-microblaze*.deb; - sudo apt install -y ./newlib-source*.deb; + sudo apt install -y $HOME/binutils-microblaze.deb; + sudo apt install -y $HOME/gcc-microblaze.deb; + sudo apt install -y $HOME/libnewlib-microblaze-dev.deb; + sudo apt install -y $HOME/libnewlib-microblaze-doc.deb; + sudo apt install -y $HOME/libnewlib-microblaze.deb; + sudo apt install -y $HOME/newlib-source.deb; # Validate that the toolchain is in the path and can be called which mb-gcc diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 3591436a4..bc8aaf69c 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -3,7 +3,7 @@ on: [push, pull_request] jobs: run: - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest steps: - name: Checkout Parent Repository uses: actions/checkout@v4.1.1 diff --git a/README.md b/README.md index a6d383add..b4e87ce3b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![CMock Unit Tests](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml/badge.svg?branch=main&event=push)](https://github.com/FreeRTOS/FreeRTOS-Kernel/actions/workflows/unit-tests.yml?query=branch%3Amain+event%3Apush+workflow%3A%22CMock+Unit+Tests%22++) -[![codecov](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel/badge.svg?branch=main)](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel) +[![codecov](https://app.codecov.io/gh/FreeRTOS/FreeRTOS-Kernel/badge.svg?branch=main)](https://codecov.io/gh/FreeRTOS/FreeRTOS-Kernel) ## Getting started diff --git a/event_groups.c b/event_groups.c index 6a2ba0761..1923bf78d 100644 --- a/event_groups.c +++ b/event_groups.c @@ -501,7 +501,7 @@ } /*-----------------------------------------------------------*/ - #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + #if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) @@ -518,7 +518,7 @@ return xReturn; } - #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ EventBits_t xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) @@ -812,7 +812,7 @@ } /*-----------------------------------------------------------*/ - #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + #if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, @@ -830,7 +830,7 @@ return xReturn; } - #endif /* if ( ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_TRACE_FACILITY == 1 ) diff --git a/examples/template_configuration/FreeRTOSConfig.h b/examples/template_configuration/FreeRTOSConfig.h index 5684e3c39..5521adb4d 100644 --- a/examples/template_configuration/FreeRTOSConfig.h +++ b/examples/template_configuration/FreeRTOSConfig.h @@ -415,6 +415,8 @@ * number of the failing assert (for example, "vAssertCalled( __FILE__, __LINE__ * )" or it can simple disable interrupts and sit in a loop to halt all * execution on the failing line for viewing in a debugger. */ + +/* *INDENT-OFF* */ #define configASSERT( x ) \ if( ( x ) == 0 ) \ { \ @@ -422,6 +424,7 @@ for( ; ; ) \ ; \ } +/* *INDENT-ON* */ /******************************************************************************/ /* FreeRTOS MPU specific definitions. *****************************************/ diff --git a/include/FreeRTOS.h b/include/FreeRTOS.h index ce8530e7d..63e2feb51 100644 --- a/include/FreeRTOS.h +++ b/include/FreeRTOS.h @@ -101,6 +101,16 @@ #define configASSERT_DEFINED 1 #endif +/* Set configENABLE_PAC and/or configENABLE_BTI to 1 to enable PAC and/or BTI + * support and 0 to disable them. These are currently used in ARMv8.1-M ports. */ +#ifndef configENABLE_PAC + #define configENABLE_PAC 0 +#endif + +#ifndef configENABLE_BTI + #define configENABLE_BTI 0 +#endif + /* Basic FreeRTOS definitions. */ #include "projdefs.h" @@ -3040,16 +3050,6 @@ #define configCONTROL_INFINITE_LOOP() #endif -/* Set configENABLE_PAC and/or configENABLE_BTI to 1 to enable PAC and/or BTI - * support and 0 to disable them. These are currently used in ARMv8.1-M ports. */ -#ifndef configENABLE_PAC - #define configENABLE_PAC 0 -#endif - -#ifndef configENABLE_BTI - #define configENABLE_BTI 0 -#endif - /* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using * dynamically allocated RAM, in which case when any task is deleted it is known * that both the task's stack and TCB need to be freed. Sometimes the diff --git a/include/croutine.h b/include/croutine.h index 25f4caec8..a5e2e4462 100644 --- a/include/croutine.h +++ b/include/croutine.h @@ -246,7 +246,10 @@ void vCoRoutineSchedule( void ); * \defgroup crSTART crSTART * \ingroup Tasks */ + +/* *INDENT-OFF* */ #define crEND() } +/* *INDENT-ON* */ /* * These macros are intended for internal use by the co-routine implementation diff --git a/include/event_groups.h b/include/event_groups.h index 9e6348687..d42c87b28 100644 --- a/include/event_groups.h +++ b/include/event_groups.h @@ -452,13 +452,10 @@ EventBits_t xEventGroupClearBits( EventGroupHandle_t xEventGroup, * \defgroup xEventGroupClearBitsFromISR xEventGroupClearBitsFromISR * \ingroup EventGroup */ -#if ( configUSE_TRACE_FACILITY == 1 ) +#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; -#else - #define xEventGroupClearBitsFromISR( xEventGroup, uxBitsToClear ) \ - xTimerPendFunctionCallFromISR( vEventGroupClearBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToClear ), NULL ) -#endif +#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /** * event_groups.h @@ -607,14 +604,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * \defgroup xEventGroupSetBitsFromISR xEventGroupSetBitsFromISR * \ingroup EventGroup */ -#if ( configUSE_TRACE_FACILITY == 1 ) +#if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; -#else - #define xEventGroupSetBitsFromISR( xEventGroup, uxBitsToSet, pxHigherPriorityTaskWoken ) \ - xTimerPendFunctionCallFromISR( vEventGroupSetBitsCallback, ( void * ) ( xEventGroup ), ( uint32_t ) ( uxBitsToSet ), ( pxHigherPriorityTaskWoken ) ) -#endif +#endif /* if ( ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /** * event_groups.h diff --git a/include/list.h b/include/list.h index b64450c72..b6e0d34f4 100644 --- a/include/list.h +++ b/include/list.h @@ -44,7 +44,7 @@ * * In addition to it's value, each list item contains a pointer to the next * item in the list (pxNext), a pointer to the list it is in (pxContainer) - * and a pointer to back to the object that contains it. These later two + * and a pointer back to the object that contains it. These later two * pointers are included for efficiency of list manipulation. There is * effectively a two way link between the object containing the list item and * the list item itself. diff --git a/include/mpu_prototypes.h b/include/mpu_prototypes.h index 9df2a5762..b4c0f4745 100644 --- a/include/mpu_prototypes.h +++ b/include/mpu_prototypes.h @@ -409,13 +409,16 @@ EventBits_t MPU_xEventGroupSync( EventGroupHandle_t xEventGroup, BaseType_t MPU_xEventGroupGetStaticBuffer( EventGroupHandle_t xEventGroup, StaticEventGroup_t ** ppxEventGroupBuffer ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToClear ) PRIVILEGED_FUNCTION; -BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, - const EventBits_t uxBitsToSet, - BaseType_t * pxHigherPriorityTaskWoken ) PRIVILEGED_FUNCTION; EventBits_t MPU_xEventGroupGetBitsFromISR( EventGroupHandle_t xEventGroup ) PRIVILEGED_FUNCTION; +#if ( configUSE_MPU_WRAPPERS_V1 == 0 ) + BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToClear ) FREERTOS_SYSTEM_CALL; + BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, + const EventBits_t uxBitsToSet, + BaseType_t * pxHigherPriorityTaskWoken ) FREERTOS_SYSTEM_CALL; +#endif /* #if ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ + /* MPU versions of message/stream_buffer.h API functions. */ size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void * pvTxData, diff --git a/include/semphr.h b/include/semphr.h index 8977acadb..7b44d78c0 100644 --- a/include/semphr.h +++ b/include/semphr.h @@ -37,8 +37,8 @@ typedef QueueHandle_t SemaphoreHandle_t; -#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( uint8_t ) 1U ) -#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( uint8_t ) 0U ) +#define semBINARY_SEMAPHORE_QUEUE_LENGTH ( ( UBaseType_t ) 1U ) +#define semSEMAPHORE_QUEUE_ITEM_LENGTH ( ( UBaseType_t ) 0U ) #define semGIVE_BLOCK_TIME ( ( TickType_t ) 0U ) diff --git a/portable/ARMv8M/non_secure/port.c b/portable/ARMv8M/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/ARMv8M/non_secure/port.c +++ b/portable/ARMv8M/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt index 5e43877bb..53b6f58d6 100644 --- a/portable/CMakeLists.txt +++ b/portable/CMakeLists.txt @@ -769,6 +769,7 @@ add_library(freertos_kernel_port OBJECT if( FREERTOS_PORT MATCHES "GCC_ARM_CM(3|4)_MPU" OR FREERTOS_PORT STREQUAL "IAR_ARM_CM4F_MPU" OR FREERTOS_PORT STREQUAL "RVDS_ARM_CM4_MPU" OR + FREERTOS_PORT STREQUAL "GCC_ARM_CRX_MPU" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NTZ_NONSECURE" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(23|33|55|85)_NONSECURE" OR FREERTOS_PORT MATCHES "GCC_ARM_CM(33|55|85)_TFM" OR diff --git a/portable/Common/mpu_wrappers_v2.c b/portable/Common/mpu_wrappers_v2.c index e92aca0f5..70082b829 100644 --- a/portable/Common/mpu_wrappers_v2.c +++ b/portable/Common/mpu_wrappers_v2.c @@ -1059,8 +1059,8 @@ configRUN_TIME_COUNTER_TYPE * pulTotalRunTime ) /* PRIVILEGED_FUNCTION */ { UBaseType_t uxReturn = 0; - UBaseType_t xIsTaskStatusArrayWriteable = pdFALSE; - UBaseType_t xIsTotalRunTimeWriteable = pdFALSE; + BaseType_t xIsTaskStatusArrayWriteable = pdFALSE; + BaseType_t xIsTotalRunTimeWriteable = pdFALSE; uint32_t ulArraySize = ( uint32_t ) uxArraySize; uint32_t ulTaskStatusSize = ( uint32_t ) sizeof( TaskStatus_t ); @@ -4282,7 +4282,7 @@ #endif /* #if ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configUSE_EVENT_GROUPS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t MPU_xEventGroupClearBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToClear ) /* PRIVILEGED_FUNCTION */ @@ -4306,10 +4306,10 @@ return xReturn; } - #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ - #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) + #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) BaseType_t MPU_xEventGroupSetBitsFromISR( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, @@ -4334,7 +4334,7 @@ return xReturn; } - #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( configUSE_TRACE_FACILITY == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ + #endif /* #if ( ( configUSE_EVENT_GROUPS == 1 ) && ( INCLUDE_xTimerPendFunctionCall == 1 ) && ( configUSE_TIMERS == 1 ) ) */ /*-----------------------------------------------------------*/ #if ( configUSE_EVENT_GROUPS == 1 ) diff --git a/portable/GCC/ARM_CM0/port.c b/portable/GCC/ARM_CM0/port.c index c3053c543..fd3229a76 100644 --- a/portable/GCC/ARM_CM0/port.c +++ b/portable/GCC/ARM_CM0/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -915,7 +917,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; uint32_t ulSystemCallLocation, i; - const uint32_t ulStackFrameSize = 8; + /* Hardware Saved Stack Frame Size upon Exception entry: + * Basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + */ + const uint32_t ulHardwareSavedExceptionFrameSize = 8; #if defined( __ARMCC_VERSION ) @@ -955,10 +960,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -981,7 +986,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1036,7 +1041,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; uint32_t ulSystemCallLocation, i; - const uint32_t ulStackFrameSize = 8; + /* Hardware Saved Stack Frame Size upon Exception entry: + * Basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + */ + const uint32_t ulHardwareSavedExceptionFrameSize = 8; #if defined( __ARMCC_VERSION ) @@ -1072,10 +1080,10 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } diff --git a/portable/GCC/ARM_CM23/non_secure/port.c b/portable/GCC/ARM_CM23/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM23/non_secure/port.c +++ b/portable/GCC/ARM_CM23/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM23_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM33/non_secure/port.c b/portable/GCC/ARM_CM33/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM33/non_secure/port.c +++ b/portable/GCC/ARM_CM33/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM33_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM35P/non_secure/port.c b/portable/GCC/ARM_CM35P/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM35P/non_secure/port.c +++ b/portable/GCC/ARM_CM35P/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM35P_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM3_MPU/port.c b/portable/GCC/ARM_CM3_MPU/port.c index cc91c5611..8c4dd7800 100644 --- a/portable/GCC/ARM_CM3_MPU/port.c +++ b/portable/GCC/ARM_CM3_MPU/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -484,7 +486,10 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; uint32_t ulSystemCallLocation, i; - const uint32_t ulStackFrameSize = 8; + /* Hardware Saved Stack Frame Size upon Exception entry: + * Basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + */ + const uint32_t ulHardwareSavedExceptionFrameSize = 8; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -520,10 +525,10 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -541,7 +546,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Store the value of the Link Register before the SVC was raised. * It contains the address of the caller of the System Call entry @@ -594,7 +599,10 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; uint32_t ulSystemCallLocation, i; - const uint32_t ulStackFrameSize = 8; + /* Hardware Saved Stack Frame Size upon Exception entry: + * Basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + */ + const uint32_t ulHardwareSavedExceptionFrameSize = 8; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -626,10 +634,10 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } diff --git a/portable/GCC/ARM_CM4_MPU/port.c b/portable/GCC/ARM_CM4_MPU/port.c index d6a4931b5..79f5e76d5 100644 --- a/portable/GCC/ARM_CM4_MPU/port.c +++ b/portable/GCC/ARM_CM4_MPU/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -518,7 +520,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -553,10 +555,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -566,14 +572,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -591,7 +597,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Store the value of the Link Register before the SVC was raised. * It contains the address of the caller of the System Call entry @@ -644,7 +650,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -675,10 +681,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -688,14 +698,14 @@ void vSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } diff --git a/portable/GCC/ARM_CM55/non_secure/port.c b/portable/GCC/ARM_CM55/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM55/non_secure/port.c +++ b/portable/GCC/ARM_CM55/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM55_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM85/non_secure/port.c b/portable/GCC/ARM_CM85/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM85/non_secure/port.c +++ b/portable/GCC/ARM_CM85/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/GCC/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/GCC/ARM_CM85_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S index 142486adf..caf31ff76 100644 --- a/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S +++ b/portable/GCC/ARM_CRx_MPU/mpu_wrappers_v2_asm.S @@ -30,7 +30,7 @@ .arm .syntax unified - .section freertos_system_calls + .section freertos_system_calls, "ax" #define FREERTOS_ASSEMBLY #include "FreeRTOSConfig.h" diff --git a/portable/GCC/ARM_CRx_MPU/portASM.S b/portable/GCC/ARM_CRx_MPU/portASM.S index bc0345a80..2b6f22ef2 100644 --- a/portable/GCC/ARM_CRx_MPU/portASM.S +++ b/portable/GCC/ARM_CRx_MPU/portASM.S @@ -28,7 +28,7 @@ .arm .syntax unified - .section privileged_functions + .section privileged_functions, "ax" #define FREERTOS_ASSEMBLY #include "portmacro_asm.h" diff --git a/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h b/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h index 4d8a5fb53..c10869eb4 100644 --- a/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h +++ b/portable/GCC/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h @@ -80,22 +80,22 @@ csrr t2, lpcount0 csrr t3, lpstart1 csrr t4, lpend1 csrr t5, lpcount1 -sw t0, 1 * portWORD_SIZE( sp ) -sw t1, 2 * portWORD_SIZE( sp ) -sw t2, 3 * portWORD_SIZE( sp ) -sw t3, 4 * portWORD_SIZE( sp ) -sw t4, 5 * portWORD_SIZE( sp ) -sw t5, 6 * portWORD_SIZE( sp ) +sw t0, 2 * portWORD_SIZE( sp ) +sw t1, 3 * portWORD_SIZE( sp ) +sw t2, 4 * portWORD_SIZE( sp ) +sw t3, 5 * portWORD_SIZE( sp ) +sw t4, 6 * portWORD_SIZE( sp ) +sw t5, 7 * portWORD_SIZE( sp ) .endm /* Restore the additional registers found on the Pulpino. */ .macro portasmRESTORE_ADDITIONAL_REGISTERS -lw t0, 1 * portWORD_SIZE( sp ) /* Load additional registers into accessible temporary registers. */ -lw t1, 2 * portWORD_SIZE( sp ) -lw t2, 3 * portWORD_SIZE( sp ) -lw t3, 4 * portWORD_SIZE( sp ) -lw t4, 5 * portWORD_SIZE( sp ) -lw t5, 6 * portWORD_SIZE( sp ) +lw t0, 2 * portWORD_SIZE( sp ) /* Load additional registers into accessible temporary registers. */ +lw t1, 3 * portWORD_SIZE( sp ) +lw t2, 4 * portWORD_SIZE( sp ) +lw t3, 5 * portWORD_SIZE( sp ) +lw t4, 6 * portWORD_SIZE( sp ) +lw t5, 7 * portWORD_SIZE( sp ) csrw lpstart0, t0 csrw lpend0, t1 csrw lpcount0, t2 diff --git a/portable/GCC/RISC-V/port.c b/portable/GCC/RISC-V/port.c index e52fe8b12..8fe7a25d5 100644 --- a/portable/GCC/RISC-V/port.c +++ b/portable/GCC/RISC-V/port.c @@ -90,7 +90,7 @@ void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) ); uint64_t ullNextTime = 0ULL; const uint64_t * pullNextTime = &ullNextTime; const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */ -uint64_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; +UBaseType_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; volatile uint64_t * pullMachineTimerCompareRegister = NULL; /* Holds the critical nesting value - deliberately non-zero at start up to diff --git a/portable/GCC/RISC-V/portASM.S b/portable/GCC/RISC-V/portASM.S index 99613ada6..3d1d058cd 100644 --- a/portable/GCC/RISC-V/portASM.S +++ b/portable/GCC/RISC-V/portASM.S @@ -162,7 +162,6 @@ definitions. */ * where the global and thread pointers are currently assumed to be constant so * are not saved: * - * mstatus * xCriticalNesting * x31 * x30 @@ -192,18 +191,13 @@ definitions. */ * x6 * x5 * portTASK_RETURN_ADDRESS + * [FPU registers (when enabled/available) go here] + * [VPU registers (when enabled/available) go here] * [chip specific registers go here] + * mstatus * pxCode */ pxPortInitialiseStack: - csrr t0, mstatus /* Obtain current mstatus value. */ - andi t0, t0, ~0x8 /* Ensure interrupts are disabled when the stack is restored within an ISR. Required when a task is created after the schedulre has been started, otherwise interrupts would be disabled anyway. */ - addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */ - slli t1, t1, 4 - or t0, t0, t1 /* Set MPIE and MPP bits in mstatus value. */ - - addi a0, a0, -portWORD_SIZE - store_x t0, 0(a0) /* mstatus onto the stack. */ addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */ store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */ @@ -212,10 +206,12 @@ pxPortInitialiseStack: #else addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x10-x31. */ #endif - store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */ - addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9 + taskReturnAddress. */ + store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register x10/a0 on the stack. */ + + addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9 + taskReturnAddress (register x1). */ load_x t0, xTaskReturnAddress store_x t0, 0(a0) /* Return address onto the stack. */ + addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ chip_specific_stack_frame: /* First add any chip specific registers to the stack frame being created. */ beq t0, x0, 1f /* No more chip specific registers to save. */ @@ -224,6 +220,31 @@ chip_specific_stack_frame: /* First add any chip specific registers addi t0, t0, -1 /* Decrement the count of chip specific registers remaining. */ j chip_specific_stack_frame /* Until no more chip specific registers. */ 1: + csrr t0, mstatus /* Obtain current mstatus value. */ + andi t0, t0, ~0x8 /* Ensure interrupts are disabled when the stack is restored within an ISR. Required when a task is created after the scheduler has been started, otherwise interrupts would be disabled anyway. */ + addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE=1 and MPP=M_Mode in mstatus. */ + slli t1, t1, 4 + or t0, t0, t1 /* Set MPIE and MPP bits in mstatus value. */ + +#if( configENABLE_FPU == 1 ) + /* Mark the FPU as clean in the mstatus value. */ + li t1, ~MSTATUS_FS_MASK + and t0, t0, t1 + li t1, MSTATUS_FS_CLEAN + or t0, t0, t1 +#endif + +#if( configENABLE_VPU == 1 ) + /* Mark the VPU as clean in the mstatus value. */ + li t1, ~MSTATUS_VS_MASK + and t0, t0, t1 + li t1, MSTATUS_VS_CLEAN + or t0, t0, t1 +#endif + + addi a0, a0, -portWORD_SIZE + store_x t0, 0(a0) /* mstatus onto the stack. */ + addi a0, a0, -portWORD_SIZE store_x a1, 0(a0) /* mret value (pxCode parameter) onto the stack. */ ret @@ -235,46 +256,46 @@ xPortStartFirstTask: load_x x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */ + load_x x5, 1 * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */ + addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */ + csrw mstatus, x5 /* Interrupts enabled from here! */ + portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ - load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */ - load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */ - load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */ - load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */ - load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */ - load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */ - load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */ - load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */ - load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */ + load_x x7, 5 * portWORD_SIZE( sp ) /* t2 */ + load_x x8, 6 * portWORD_SIZE( sp ) /* s0/fp */ + load_x x9, 7 * portWORD_SIZE( sp ) /* s1 */ + load_x x10, 8 * portWORD_SIZE( sp ) /* a0 */ + load_x x11, 9 * portWORD_SIZE( sp ) /* a1 */ + load_x x12, 10 * portWORD_SIZE( sp ) /* a2 */ + load_x x13, 11 * portWORD_SIZE( sp ) /* a3 */ + load_x x14, 12 * portWORD_SIZE( sp ) /* a4 */ + load_x x15, 13 * portWORD_SIZE( sp ) /* a5 */ #ifndef __riscv_32e - load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */ - load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */ - load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */ - load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */ - load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */ - load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */ - load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */ - load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */ - load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */ - load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */ - load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */ - load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */ - load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */ - load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */ - load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */ - load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */ + load_x x16, 14 * portWORD_SIZE( sp ) /* a6 */ + load_x x17, 15 * portWORD_SIZE( sp ) /* a7 */ + load_x x18, 16 * portWORD_SIZE( sp ) /* s2 */ + load_x x19, 17 * portWORD_SIZE( sp ) /* s3 */ + load_x x20, 18 * portWORD_SIZE( sp ) /* s4 */ + load_x x21, 19 * portWORD_SIZE( sp ) /* s5 */ + load_x x22, 20 * portWORD_SIZE( sp ) /* s6 */ + load_x x23, 21 * portWORD_SIZE( sp ) /* s7 */ + load_x x24, 22 * portWORD_SIZE( sp ) /* s8 */ + load_x x25, 23 * portWORD_SIZE( sp ) /* s9 */ + load_x x26, 24 * portWORD_SIZE( sp ) /* s10 */ + load_x x27, 25 * portWORD_SIZE( sp ) /* s11 */ + load_x x28, 26 * portWORD_SIZE( sp ) /* t3 */ + load_x x29, 27 * portWORD_SIZE( sp ) /* t4 */ + load_x x30, 28 * portWORD_SIZE( sp ) /* t5 */ + load_x x31, 29 * portWORD_SIZE( sp ) /* t6 */ #endif load_x x5, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ load_x x6, pxCriticalNesting /* Load the address of xCriticalNesting into x6. */ store_x x5, 0( x6 ) /* Restore the critical nesting value for this task. */ - load_x x5, portMSTATUS_OFFSET * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */ - addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */ - csrrw x0, mstatus, x5 /* Interrupts enabled from here! */ - - load_x x5, 2 * portWORD_SIZE( sp ) /* Initial x5 (t0) value. */ - load_x x6, 3 * portWORD_SIZE( sp ) /* Initial x6 (t1) value. */ + load_x x5, 3 * portWORD_SIZE( sp ) /* Initial x5 (t0) value. */ + load_x x6, 4 * portWORD_SIZE( sp ) /* Initial x6 (t1) value. */ addi sp, sp, portCONTEXT_SIZE ret diff --git a/portable/GCC/RISC-V/portContext.h b/portable/GCC/RISC-V/portContext.h index 6baae753d..95b84dd1a 100644 --- a/portable/GCC/RISC-V/portContext.h +++ b/portable/GCC/RISC-V/portContext.h @@ -29,6 +29,14 @@ #ifndef PORTCONTEXT_H #define PORTCONTEXT_H +#ifndef configENABLE_FPU + #define configENABLE_FPU 0 +#endif + +#ifndef configENABLE_VPU + #define configENABLE_VPU 0 +#endif + #if __riscv_xlen == 64 #define portWORD_SIZE 8 #define store_x sd @@ -50,65 +58,311 @@ * notes at the top of portASM.S file. */ #ifdef __riscv_32e #define portCONTEXT_SIZE ( 15 * portWORD_SIZE ) - #define portCRITICAL_NESTING_OFFSET 13 - #define portMSTATUS_OFFSET 14 + #define portCRITICAL_NESTING_OFFSET 14 #else #define portCONTEXT_SIZE ( 31 * portWORD_SIZE ) - #define portCRITICAL_NESTING_OFFSET 29 - #define portMSTATUS_OFFSET 30 + #define portCRITICAL_NESTING_OFFSET 30 #endif +#if ( configENABLE_FPU == 1 ) + /* Bit [14:13] in the mstatus encode the status of FPU state which is one of + * the following values: + * 1. Value: 0, Meaning: Off. + * 2. Value: 1, Meaning: Initial. + * 3. Value: 2, Meaning: Clean. + * 4. Value: 3, Meaning: Dirty. + */ + #define MSTATUS_FS_MASK 0x6000 + #define MSTATUS_FS_INITIAL 0x2000 + #define MSTATUS_FS_CLEAN 0x4000 + #define MSTATUS_FS_DIRTY 0x6000 + #define MSTATUS_FS_OFFSET 13 + + #ifdef __riscv_fdiv + #if __riscv_flen == 32 + #define load_f flw + #define store_f fsw + #elif __riscv_flen == 64 + #define load_f fld + #define store_f fsd + #else + #error Assembler did not define __riscv_flen + #endif + + #define portFPU_REG_SIZE ( __riscv_flen / 8 ) + #define portFPU_REG_COUNT 33 /* 32 Floating point registers plus one CSR. */ + #define portFPU_REG_OFFSET( regIndex ) ( ( 2 * portWORD_SIZE ) + ( regIndex * portFPU_REG_SIZE ) ) + #define portFPU_CONTEXT_SIZE ( portFPU_REG_SIZE * portFPU_REG_COUNT ) + #else + #error configENABLE_FPU must not be set to 1 if the hardware does not have FPU + #endif +#endif + +#if ( configENABLE_VPU == 1 ) + /* Bit [10:9] in the mstatus encode the status of VPU state which is one of + * the following values: + * 1. Value: 0, Meaning: Off. + * 2. Value: 1, Meaning: Initial. + * 3. Value: 2, Meaning: Clean. + * 4. Value: 3, Meaning: Dirty. + */ + #define MSTATUS_VS_MASK 0x600 + #define MSTATUS_VS_INITIAL 0x200 + #define MSTATUS_VS_CLEAN 0x400 + #define MSTATUS_VS_DIRTY 0x600 + #define MSTATUS_VS_OFFSET 9 + + #ifndef __riscv_vector + #error configENABLE_VPU must not be set to 1 if the hardware does not have VPU + #endif +#endif /*-----------------------------------------------------------*/ .extern pxCurrentTCB - .extern xISRStackTop - .extern xCriticalNesting - .extern pxCriticalNesting +.extern xISRStackTop +.extern xCriticalNesting +.extern pxCriticalNesting +/*-----------------------------------------------------------*/ + + .macro portcontexSAVE_FPU_CONTEXT +addi sp, sp, -( portFPU_CONTEXT_SIZE ) +/* Store the FPU registers. */ +store_f f0, portFPU_REG_OFFSET( 0 )( sp ) +store_f f1, portFPU_REG_OFFSET( 1 )( sp ) +store_f f2, portFPU_REG_OFFSET( 2 )( sp ) +store_f f3, portFPU_REG_OFFSET( 3 )( sp ) +store_f f4, portFPU_REG_OFFSET( 4 )( sp ) +store_f f5, portFPU_REG_OFFSET( 5 )( sp ) +store_f f6, portFPU_REG_OFFSET( 6 )( sp ) +store_f f7, portFPU_REG_OFFSET( 7 )( sp ) +store_f f8, portFPU_REG_OFFSET( 8 )( sp ) +store_f f9, portFPU_REG_OFFSET( 9 )( sp ) +store_f f10, portFPU_REG_OFFSET( 10 )( sp ) +store_f f11, portFPU_REG_OFFSET( 11 )( sp ) +store_f f12, portFPU_REG_OFFSET( 12 )( sp ) +store_f f13, portFPU_REG_OFFSET( 13 )( sp ) +store_f f14, portFPU_REG_OFFSET( 14 )( sp ) +store_f f15, portFPU_REG_OFFSET( 15 )( sp ) +store_f f16, portFPU_REG_OFFSET( 16 )( sp ) +store_f f17, portFPU_REG_OFFSET( 17 )( sp ) +store_f f18, portFPU_REG_OFFSET( 18 )( sp ) +store_f f19, portFPU_REG_OFFSET( 19 )( sp ) +store_f f20, portFPU_REG_OFFSET( 20 )( sp ) +store_f f21, portFPU_REG_OFFSET( 21 )( sp ) +store_f f22, portFPU_REG_OFFSET( 22 )( sp ) +store_f f23, portFPU_REG_OFFSET( 23 )( sp ) +store_f f24, portFPU_REG_OFFSET( 24 )( sp ) +store_f f25, portFPU_REG_OFFSET( 25 )( sp ) +store_f f26, portFPU_REG_OFFSET( 26 )( sp ) +store_f f27, portFPU_REG_OFFSET( 27 )( sp ) +store_f f28, portFPU_REG_OFFSET( 28 )( sp ) +store_f f29, portFPU_REG_OFFSET( 29 )( sp ) +store_f f30, portFPU_REG_OFFSET( 30 )( sp ) +store_f f31, portFPU_REG_OFFSET( 31 )( sp ) +csrr t0, fcsr +store_x t0, portFPU_REG_OFFSET( 32 )( sp ) + .endm +/*-----------------------------------------------------------*/ + + .macro portcontextRESTORE_FPU_CONTEXT +/* Restore the FPU registers. */ +load_f f0, portFPU_REG_OFFSET( 0 )( sp ) +load_f f1, portFPU_REG_OFFSET( 1 )( sp ) +load_f f2, portFPU_REG_OFFSET( 2 )( sp ) +load_f f3, portFPU_REG_OFFSET( 3 )( sp ) +load_f f4, portFPU_REG_OFFSET( 4 )( sp ) +load_f f5, portFPU_REG_OFFSET( 5 )( sp ) +load_f f6, portFPU_REG_OFFSET( 6 )( sp ) +load_f f7, portFPU_REG_OFFSET( 7 )( sp ) +load_f f8, portFPU_REG_OFFSET( 8 )( sp ) +load_f f9, portFPU_REG_OFFSET( 9 )( sp ) +load_f f10, portFPU_REG_OFFSET( 10 )( sp ) +load_f f11, portFPU_REG_OFFSET( 11 )( sp ) +load_f f12, portFPU_REG_OFFSET( 12 )( sp ) +load_f f13, portFPU_REG_OFFSET( 13 )( sp ) +load_f f14, portFPU_REG_OFFSET( 14 )( sp ) +load_f f15, portFPU_REG_OFFSET( 15 )( sp ) +load_f f16, portFPU_REG_OFFSET( 16 )( sp ) +load_f f17, portFPU_REG_OFFSET( 17 )( sp ) +load_f f18, portFPU_REG_OFFSET( 18 )( sp ) +load_f f19, portFPU_REG_OFFSET( 19 )( sp ) +load_f f20, portFPU_REG_OFFSET( 20 )( sp ) +load_f f21, portFPU_REG_OFFSET( 21 )( sp ) +load_f f22, portFPU_REG_OFFSET( 22 )( sp ) +load_f f23, portFPU_REG_OFFSET( 23 )( sp ) +load_f f24, portFPU_REG_OFFSET( 24 )( sp ) +load_f f25, portFPU_REG_OFFSET( 25 )( sp ) +load_f f26, portFPU_REG_OFFSET( 26 )( sp ) +load_f f27, portFPU_REG_OFFSET( 27 )( sp ) +load_f f28, portFPU_REG_OFFSET( 28 )( sp ) +load_f f29, portFPU_REG_OFFSET( 29 )( sp ) +load_f f30, portFPU_REG_OFFSET( 30 )( sp ) +load_f f31, portFPU_REG_OFFSET( 31 )( sp ) +load_x t0, portFPU_REG_OFFSET( 32 )( sp ) +csrw fcsr, t0 +addi sp, sp, ( portFPU_CONTEXT_SIZE ) + .endm +/*-----------------------------------------------------------*/ + + .macro portcontexSAVE_VPU_CONTEXT +/* Un-reserve the space reserved for mstatus and epc. */ +add sp, sp, ( 2 * portWORD_SIZE ) + +csrr t0, vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */ +slli t0, t0, 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */ +neg t0, t0 + +/* Store the vector registers in group of 8. */ +add sp, sp, t0 +vs8r.v v0, (sp) /* Store v0-v7. */ +add sp, sp, t0 +vs8r.v v8, (sp) /* Store v8-v15. */ +add sp, sp, t0 +vs8r.v v16, (sp) /* Store v16-v23. */ +add sp, sp, t0 +vs8r.v v24, (sp) /* Store v24-v31. */ + +/* Store the VPU CSRs. */ +addi sp, sp, -( 4 * portWORD_SIZE ) +csrr t0, vstart +store_x t0, 0 * portWORD_SIZE( sp ) +csrr t0, vcsr +store_x t0, 1 * portWORD_SIZE( sp ) +csrr t0, vl +store_x t0, 2 * portWORD_SIZE( sp ) +csrr t0, vtype +store_x t0, 3 * portWORD_SIZE( sp ) + +/* Re-reserve the space for mstatus and epc. */ +add sp, sp, -( 2 * portWORD_SIZE ) + .endm +/*-----------------------------------------------------------*/ + + .macro portcontextRESTORE_VPU_CONTEXT +/* Un-reserve the space reserved for mstatus and epc. */ +add sp, sp, ( 2 * portWORD_SIZE ) + +/* Restore the VPU CSRs. */ +load_x t0, 0 * portWORD_SIZE( sp ) +csrw vstart, t0 +load_x t0, 1 * portWORD_SIZE( sp ) +csrw vcsr, t0 +load_x t0, 2 * portWORD_SIZE( sp ) +load_x t1, 3 * portWORD_SIZE( sp ) +vsetvl x0, t0, t1 /* vlen and vtype can only be updated by using vset*vl* instructions. */ +addi sp, sp, ( 4 * portWORD_SIZE ) + +csrr t0, vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */ +slli t0, t0, 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */ + +/* Restore the vector registers. */ +vl8r.v v24, (sp) +add sp, sp, t0 +vl8r.v v16, (sp) +add sp, sp, t0 +vl8r.v v8, (sp) +add sp, sp, t0 +vl8r.v v0, (sp) +add sp, sp, t0 + +/* Re-reserve the space for mstatus and epc. */ +add sp, sp, -( 2 * portWORD_SIZE ) + .endm /*-----------------------------------------------------------*/ .macro portcontextSAVE_CONTEXT_INTERNAL addi sp, sp, -portCONTEXT_SIZE -store_x x1, 1 * portWORD_SIZE( sp ) -store_x x5, 2 * portWORD_SIZE( sp ) -store_x x6, 3 * portWORD_SIZE( sp ) -store_x x7, 4 * portWORD_SIZE( sp ) -store_x x8, 5 * portWORD_SIZE( sp ) -store_x x9, 6 * portWORD_SIZE( sp ) -store_x x10, 7 * portWORD_SIZE( sp ) -store_x x11, 8 * portWORD_SIZE( sp ) -store_x x12, 9 * portWORD_SIZE( sp ) -store_x x13, 10 * portWORD_SIZE( sp ) -store_x x14, 11 * portWORD_SIZE( sp ) -store_x x15, 12 * portWORD_SIZE( sp ) +store_x x1, 2 * portWORD_SIZE( sp ) +store_x x5, 3 * portWORD_SIZE( sp ) +store_x x6, 4 * portWORD_SIZE( sp ) +store_x x7, 5 * portWORD_SIZE( sp ) +store_x x8, 6 * portWORD_SIZE( sp ) +store_x x9, 7 * portWORD_SIZE( sp ) +store_x x10, 8 * portWORD_SIZE( sp ) +store_x x11, 9 * portWORD_SIZE( sp ) +store_x x12, 10 * portWORD_SIZE( sp ) +store_x x13, 11 * portWORD_SIZE( sp ) +store_x x14, 12 * portWORD_SIZE( sp ) +store_x x15, 13 * portWORD_SIZE( sp ) #ifndef __riscv_32e - store_x x16, 13 * portWORD_SIZE( sp ) - store_x x17, 14 * portWORD_SIZE( sp ) - store_x x18, 15 * portWORD_SIZE( sp ) - store_x x19, 16 * portWORD_SIZE( sp ) - store_x x20, 17 * portWORD_SIZE( sp ) - store_x x21, 18 * portWORD_SIZE( sp ) - store_x x22, 19 * portWORD_SIZE( sp ) - store_x x23, 20 * portWORD_SIZE( sp ) - store_x x24, 21 * portWORD_SIZE( sp ) - store_x x25, 22 * portWORD_SIZE( sp ) - store_x x26, 23 * portWORD_SIZE( sp ) - store_x x27, 24 * portWORD_SIZE( sp ) - store_x x28, 25 * portWORD_SIZE( sp ) - store_x x29, 26 * portWORD_SIZE( sp ) - store_x x30, 27 * portWORD_SIZE( sp ) - store_x x31, 28 * portWORD_SIZE( sp ) + store_x x16, 14 * portWORD_SIZE( sp ) + store_x x17, 15 * portWORD_SIZE( sp ) + store_x x18, 16 * portWORD_SIZE( sp ) + store_x x19, 17 * portWORD_SIZE( sp ) + store_x x20, 18 * portWORD_SIZE( sp ) + store_x x21, 19 * portWORD_SIZE( sp ) + store_x x22, 20 * portWORD_SIZE( sp ) + store_x x23, 21 * portWORD_SIZE( sp ) + store_x x24, 22 * portWORD_SIZE( sp ) + store_x x25, 23 * portWORD_SIZE( sp ) + store_x x26, 24 * portWORD_SIZE( sp ) + store_x x27, 25 * portWORD_SIZE( sp ) + store_x x28, 26 * portWORD_SIZE( sp ) + store_x x29, 27 * portWORD_SIZE( sp ) + store_x x30, 28 * portWORD_SIZE( sp ) + store_x x31, 29 * portWORD_SIZE( sp ) #endif /* ifndef __riscv_32e */ load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */ store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ +#if( configENABLE_FPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 1f /* If FPU status is not dirty, do not save FPU registers. */ -csrr t0, mstatus /* Required for MPIE bit. */ -store_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) + portcontexSAVE_FPU_CONTEXT +1: +#endif +#if( configENABLE_VPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 2f /* If VPU status is not dirty, do not save FPU registers. */ + + portcontexSAVE_VPU_CONTEXT +2: +#endif portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */ +csrr t0, mstatus +store_x t0, 1 * portWORD_SIZE( sp ) + +#if( configENABLE_FPU == 1 ) + /* Mark the FPU as clean, if it was dirty and we saved FPU registers. */ + srl t1, t0, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 3f + + li t1, ~MSTATUS_FS_MASK + and t0, t0, t1 + li t1, MSTATUS_FS_CLEAN + or t0, t0, t1 + csrw mstatus, t0 +3: +#endif + +#if( configENABLE_VPU == 1 ) + /* Mark the VPU as clean, if it was dirty and we saved VPU registers. */ + srl t1, t0, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 4f + + li t1, ~MSTATUS_VS_MASK + and t0, t0, t1 + li t1, MSTATUS_VS_CLEAN + or t0, t0, t1 + csrw mstatus, t0 +4: +#endif + load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */ store_x sp, 0 ( t0 ) /* Write sp to first TCB member. */ @@ -142,46 +396,68 @@ load_x sp, 0 ( t1 ) /* Read sp from first TCB member. */ load_x t0, 0 ( sp ) csrw mepc, t0 +/* Restore mstatus register. */ +load_x t0, 1 * portWORD_SIZE( sp ) +csrw mstatus, t0 + /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */ portasmRESTORE_ADDITIONAL_REGISTERS -/* Load mstatus with the interrupt enable bits used by the task. */ -load_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) -csrw mstatus, t0 /* Required for MPIE bit. */ +#if( configENABLE_VPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_VS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 5f /* If VPU status is not dirty, do not restore VPU registers. */ + + portcontextRESTORE_VPU_CONTEXT +5: +#endif /* ifdef portasmSTORE_VPU_CONTEXT */ + +#if( configENABLE_FPU == 1 ) + csrr t0, mstatus + srl t1, t0, MSTATUS_FS_OFFSET + andi t1, t1, 3 + addi t2, x0, 3 + bne t1, t2, 6f /* If FPU status is not dirty, do not restore FPU registers. */ + + portcontextRESTORE_FPU_CONTEXT +6: +#endif /* ifdef portasmSTORE_FPU_CONTEXT */ load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */ store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */ -load_x x1, 1 * portWORD_SIZE( sp ) -load_x x5, 2 * portWORD_SIZE( sp ) -load_x x6, 3 * portWORD_SIZE( sp ) -load_x x7, 4 * portWORD_SIZE( sp ) -load_x x8, 5 * portWORD_SIZE( sp ) -load_x x9, 6 * portWORD_SIZE( sp ) -load_x x10, 7 * portWORD_SIZE( sp ) -load_x x11, 8 * portWORD_SIZE( sp ) -load_x x12, 9 * portWORD_SIZE( sp ) -load_x x13, 10 * portWORD_SIZE( sp ) -load_x x14, 11 * portWORD_SIZE( sp ) -load_x x15, 12 * portWORD_SIZE( sp ) +load_x x1, 2 * portWORD_SIZE( sp ) +load_x x5, 3 * portWORD_SIZE( sp ) +load_x x6, 4 * portWORD_SIZE( sp ) +load_x x7, 5 * portWORD_SIZE( sp ) +load_x x8, 6 * portWORD_SIZE( sp ) +load_x x9, 7 * portWORD_SIZE( sp ) +load_x x10, 8 * portWORD_SIZE( sp ) +load_x x11, 9 * portWORD_SIZE( sp ) +load_x x12, 10 * portWORD_SIZE( sp ) +load_x x13, 11 * portWORD_SIZE( sp ) +load_x x14, 12 * portWORD_SIZE( sp ) +load_x x15, 13 * portWORD_SIZE( sp ) #ifndef __riscv_32e - load_x x16, 13 * portWORD_SIZE( sp ) - load_x x17, 14 * portWORD_SIZE( sp ) - load_x x18, 15 * portWORD_SIZE( sp ) - load_x x19, 16 * portWORD_SIZE( sp ) - load_x x20, 17 * portWORD_SIZE( sp ) - load_x x21, 18 * portWORD_SIZE( sp ) - load_x x22, 19 * portWORD_SIZE( sp ) - load_x x23, 20 * portWORD_SIZE( sp ) - load_x x24, 21 * portWORD_SIZE( sp ) - load_x x25, 22 * portWORD_SIZE( sp ) - load_x x26, 23 * portWORD_SIZE( sp ) - load_x x27, 24 * portWORD_SIZE( sp ) - load_x x28, 25 * portWORD_SIZE( sp ) - load_x x29, 26 * portWORD_SIZE( sp ) - load_x x30, 27 * portWORD_SIZE( sp ) - load_x x31, 28 * portWORD_SIZE( sp ) + load_x x16, 14 * portWORD_SIZE( sp ) + load_x x17, 15 * portWORD_SIZE( sp ) + load_x x18, 16 * portWORD_SIZE( sp ) + load_x x19, 17 * portWORD_SIZE( sp ) + load_x x20, 18 * portWORD_SIZE( sp ) + load_x x21, 19 * portWORD_SIZE( sp ) + load_x x22, 20 * portWORD_SIZE( sp ) + load_x x23, 21 * portWORD_SIZE( sp ) + load_x x24, 22 * portWORD_SIZE( sp ) + load_x x25, 23 * portWORD_SIZE( sp ) + load_x x26, 24 * portWORD_SIZE( sp ) + load_x x27, 25 * portWORD_SIZE( sp ) + load_x x28, 26 * portWORD_SIZE( sp ) + load_x x29, 27 * portWORD_SIZE( sp ) + load_x x30, 28 * portWORD_SIZE( sp ) + load_x x31, 29 * portWORD_SIZE( sp ) #endif /* ifndef __riscv_32e */ addi sp, sp, portCONTEXT_SIZE diff --git a/portable/IAR/ARM_CM23/non_secure/port.c b/portable/IAR/ARM_CM23/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM23/non_secure/port.c +++ b/portable/IAR/ARM_CM23/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM23_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM23_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM33/non_secure/port.c b/portable/IAR/ARM_CM33/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM33/non_secure/port.c +++ b/portable/IAR/ARM_CM33/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM33_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM33_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM35P/non_secure/port.c b/portable/IAR/ARM_CM35P/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM35P/non_secure/port.c +++ b/portable/IAR/ARM_CM35P/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM35P_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM4F_MPU/port.c b/portable/IAR/ARM_CM4F_MPU/port.c index 66092df01..720138f08 100644 --- a/portable/IAR/ARM_CM4F_MPU/port.c +++ b/portable/IAR/ARM_CM4F_MPU/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -459,7 +461,7 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -494,10 +496,14 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -507,14 +513,14 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -532,7 +538,7 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Store the value of the Link Register before the SVC was raised. * It contains the address of the caller of the System Call entry @@ -586,7 +592,7 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) /* Declaration when these variable are defined in code instead of being @@ -617,10 +623,14 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -630,14 +640,14 @@ void vPortSVCHandler_C( uint32_t * pulParam ) /* PRIVILEGED_FUNCTION */ else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } diff --git a/portable/IAR/ARM_CM55/non_secure/port.c b/portable/IAR/ARM_CM55/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM55/non_secure/port.c +++ b/portable/IAR/ARM_CM55/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM55_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM55_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM85/non_secure/port.c b/portable/IAR/ARM_CM85/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM85/non_secure/port.c +++ b/portable/IAR/ARM_CM85/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c index b2fd7e518..76d2b2445 100644 --- a/portable/IAR/ARM_CM85_NTZ/non_secure/port.c +++ b/portable/IAR/ARM_CM85_NTZ/non_secure/port.c @@ -1,7 +1,7 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * Copyright 2024 Arm Limited and/or its affiliates + * Copyright 2024-2025 Arm Limited and/or its affiliates * * * SPDX-License-Identifier: MIT @@ -145,13 +145,13 @@ typedef void ( * portISR_t )( void ); /** * @brief Constants required to manipulate the FPU. */ -#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ +#define portCPACR ( ( volatile uint32_t * ) 0xe000ed88 ) /* Coprocessor Access Control Register. */ #define portCPACR_CP10_VALUE ( 3UL ) #define portCPACR_CP11_VALUE portCPACR_CP10_VALUE #define portCPACR_CP10_POS ( 20UL ) #define portCPACR_CP11_POS ( 22UL ) -#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ +#define portFPCCR ( ( volatile uint32_t * ) 0xe000ef34 ) /* Floating Point Context Control Register. */ #define portFPCCR_ASPEN_POS ( 31UL ) #define portFPCCR_ASPEN_MASK ( 1UL << portFPCCR_ASPEN_POS ) #define portFPCCR_LSPEN_POS ( 30UL ) @@ -188,8 +188,8 @@ typedef void ( * portISR_t )( void ); #define portMPU_MAIR0_REG ( *( ( volatile uint32_t * ) 0xe000edc0 ) ) #define portMPU_MAIR1_REG ( *( ( volatile uint32_t * ) 0xe000edc4 ) ) -#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ -#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RBAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ +#define portMPU_RLAR_ADDRESS_MASK ( 0xffffffe0 ) /* Must be 32-byte aligned. */ #define portMPU_RBAR_ACCESS_PERMISSIONS_MASK ( 3UL << 1UL ) @@ -230,8 +230,8 @@ typedef void ( * portISR_t )( void ); #if ( portARMV8M_MINOR_VERSION >= 1 ) -/* Enable Privileged eXecute Never MPU attribute for the selected memory - * region. */ + /* Enable Privileged eXecute Never MPU attribute for the selected memory + * region. */ #define portMPU_RLAR_PRIVILEGED_EXECUTE_NEVER ( 1UL << 4UL ) #endif /* portARMV8M_MINOR_VERSION >= 1 */ @@ -241,9 +241,6 @@ typedef void ( * portISR_t )( void ); /* Enable MPU. */ #define portMPU_ENABLE_BIT ( 1UL << 0UL ) -/* Expected value of the portMPU_TYPE register. */ -#define portEXPECTED_MPU_TYPE_VALUE ( configTOTAL_MPU_REGIONS << 8UL ) - /* Extract first address of the MPU region as encoded in the * RBAR (Region Base Address Register) value. */ #define portEXTRACT_FIRST_ADDRESS_FROM_RBAR( rbar ) \ @@ -291,37 +288,37 @@ typedef void ( * portISR_t )( void ); #if ( configRUN_FREERTOS_SECURE_ONLY == 1 ) -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF FD - * 1111 1111 1111 1111 1111 1111 1111 1101 - * - * Bit[6] - 1 --> The exception was taken from the Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 1 --> The exception was taken to the Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF FD + * 1111 1111 1111 1111 1111 1111 1111 1101 + * + * Bit[6] - 1 --> The exception was taken from the Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 1 --> The exception was taken to the Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xfffffffd ) #else -/** - * @brief Initial EXC_RETURN value. - * - * FF FF FF BC - * 1111 1111 1111 1111 1111 1111 1011 1100 - * - * Bit[6] - 0 --> The exception was taken from the Non-Secure state. - * Bit[5] - 1 --> Do not skip stacking of additional state context. - * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. - * Bit[3] - 1 --> Return to the Thread mode. - * Bit[2] - 1 --> Restore registers from the process stack. - * Bit[1] - 0 --> Reserved, 0. - * Bit[0] - 0 --> The exception was taken to the Non-Secure state. - */ + /** + * @brief Initial EXC_RETURN value. + * + * FF FF FF BC + * 1111 1111 1111 1111 1111 1111 1011 1100 + * + * Bit[6] - 0 --> The exception was taken from the Non-Secure state. + * Bit[5] - 1 --> Do not skip stacking of additional state context. + * Bit[4] - 1 --> The PE did not allocate space on the stack for FP context. + * Bit[3] - 1 --> Return to the Thread mode. + * Bit[2] - 1 --> Restore registers from the process stack. + * Bit[1] - 0 --> Reserved, 0. + * Bit[0] - 0 --> The exception was taken to the Non-Secure state. + */ #define portINITIAL_EXC_RETURN ( 0xffffffbc ) #endif /* configRUN_FREERTOS_SECURE_ONLY */ @@ -401,49 +398,49 @@ static void prvTaskExitError( void ); #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Extract MPU region's access permissions from the Region Base Address - * Register (RBAR) value. - * - * @param ulRBARValue RBAR value for the MPU region. - * - * @return uint32_t Access permissions. - */ + /** + * @brief Extract MPU region's access permissions from the Region Base Address + * Register (RBAR) value. + * + * @param ulRBARValue RBAR value for the MPU region. + * + * @return uint32_t Access permissions. + */ static uint32_t prvGetRegionAccessPermissions( uint32_t ulRBARValue ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 && configUSE_MPU_WRAPPERS_V1 == 0 */ #if ( configENABLE_MPU == 1 ) -/** - * @brief Setup the Memory Protection Unit (MPU). - */ + /** + * @brief Setup the Memory Protection Unit (MPU). + */ static void prvSetupMPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU */ #if ( configENABLE_FPU == 1 ) -/** - * @brief Setup the Floating Point Unit (FPU). - */ + /** + * @brief Setup the Floating Point Unit (FPU). + */ static void prvSetupFPU( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_FPU */ #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) -/** - * @brief Configures PACBTI features. - * - * This function configures the Pointer Authentication, and Branch Target - * Identification security features as per the user configuration. It returns - * the value of the special purpose CONTROL register accordingly, and optionally - * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M - * architecture based) target supports PACBTI security feature. - * - * @param xWriteControlRegister Used to control whether the special purpose - * CONTROL register should be updated or not. - * - * @return CONTROL register value according to the configured PACBTI option. - */ + /** + * @brief Configures PACBTI features. + * + * This function configures the Pointer Authentication, and Branch Target + * Identification security features as per the user configuration. It returns + * the value of the special purpose CONTROL register accordingly, and optionally + * updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M + * architecture based) target supports PACBTI security feature. + * + * @param xWriteControlRegister Used to control whether the special purpose + * CONTROL register should be updated or not. + * + * @return CONTROL register value according to the configured PACBTI option. + */ static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister ); #endif /* configENABLE_PAC == 1 || configENABLE_BTI == 1 */ @@ -491,14 +488,14 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the system call stack so that upon returning from - * SVC, the system call stack is used. - * - * @param pulTaskStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - * @param ucSystemCallNumber The system call number of the system call. - */ + /** + * @brief Sets up the system call stack so that upon returning from + * SVC, the system call stack is used. + * + * @param pulTaskStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + * @param ucSystemCallNumber The system call number of the system call. + */ void vSystemCallEnter( uint32_t * pulTaskStack, uint32_t ulLR, uint8_t ucSystemCallNumber ) PRIVILEGED_FUNCTION; @@ -507,22 +504,22 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Raise SVC for exiting from a system call. - */ + /** + * @brief Raise SVC for exiting from a system call. + */ void vRequestSystemCallExit( void ) __attribute__( ( naked ) ) PRIVILEGED_FUNCTION; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief Sets up the task stack so that upon returning from - * SVC, the task stack is used again. - * - * @param pulSystemCallStack The current SP when the SVC was raised. - * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. - */ + /** + * @brief Sets up the task stack so that upon returning from + * SVC, the task stack is used again. + * + * @param pulSystemCallStack The current SP when the SVC was raised. + * @param ulLR The value of Link Register (EXC_RETURN) in the SVC handler. + */ void vSystemCallExit( uint32_t * pulSystemCallStack, uint32_t ulLR ) PRIVILEGED_FUNCTION; @@ -530,11 +527,11 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( configENABLE_MPU == 1 ) -/** - * @brief Checks whether or not the calling task is privileged. - * - * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. - */ + /** + * @brief Checks whether or not the calling task is privileged. + * + * @return pdTRUE if the calling task is privileged, pdFALSE otherwise. + */ BaseType_t xPortIsTaskPrivileged( void ) PRIVILEGED_FUNCTION; #endif /* configENABLE_MPU == 1 */ @@ -542,9 +539,9 @@ portDONT_DISCARD void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) PRIV #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) -/** - * @brief This variable is set to pdTRUE when the scheduler is started. - */ + /** + * @brief This variable is set to pdTRUE when the scheduler is started. + */ PRIVILEGED_DATA static BaseType_t xSchedulerRunning = pdFALSE; #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) */ @@ -557,10 +554,10 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configENABLE_TRUSTZONE == 1 ) -/** - * @brief Saved as part of the task context to indicate which context the - * task is using on the secure side. - */ + /** + * @brief Saved as part of the task context to indicate which context the + * task is using on the secure side. + */ PRIVILEGED_DATA portDONT_DISCARD volatile SecureContextHandle_t xSecureContext = portNO_SECURE_CONTEXT; #endif /* configENABLE_TRUSTZONE */ @@ -579,21 +576,21 @@ PRIVILEGED_DATA static volatile uint32_t ulCriticalNesting = 0xaaaaaaaaUL; #if ( configUSE_TICKLESS_IDLE == 1 ) -/** - * @brief The number of SysTick increments that make up one tick period. - */ + /** + * @brief The number of SysTick increments that make up one tick period. + */ PRIVILEGED_DATA static uint32_t ulTimerCountsForOneTick = 0; -/** - * @brief The maximum number of tick periods that can be suppressed is - * limited by the 24 bit resolution of the SysTick timer. - */ + /** + * @brief The maximum number of tick periods that can be suppressed is + * limited by the 24 bit resolution of the SysTick timer. + */ PRIVILEGED_DATA static uint32_t xMaximumPossibleSuppressedTicks = 0; -/** - * @brief Compensate for the CPU cycles that pass while the SysTick is - * stopped (low power functionality only). - */ + /** + * @brief Compensate for the CPU cycles that pass while the SysTick is + * stopped (low power functionality only). + */ PRIVILEGED_DATA static uint32_t ulStoppedTimerCompensation = 0; #endif /* configUSE_TICKLESS_IDLE */ /*-----------------------------------------------------------*/ @@ -925,64 +922,57 @@ static void prvTaskExitError( void ) /* The only permitted number of regions are 8 or 16. */ configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) ); - /* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */ - configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ); + /* MAIR0 - Index 0. */ + portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); + /* MAIR0 - Index 1. */ + portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); - /* Check that the MPU is present. */ - if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE ) - { - /* MAIR0 - Index 0. */ - portMPU_MAIR0_REG |= ( ( portMPU_NORMAL_MEMORY_BUFFERABLE_CACHEABLE << portMPU_MAIR_ATTR0_POS ) & portMPU_MAIR_ATTR0_MASK ); - /* MAIR0 - Index 1. */ - portMPU_MAIR0_REG |= ( ( portMPU_DEVICE_MEMORY_nGnRE << portMPU_MAIR_ATTR1_POS ) & portMPU_MAIR_ATTR1_MASK ); + /* Setup privileged flash as Read Only so that privileged tasks can + * read it but not modify. */ + portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup privileged flash as Read Only so that privileged tasks can - * read it but not modify. */ - portMPU_RNR_REG = portPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_functions_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_functions_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged flash as Read Only by both privileged and + * unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged flash as Read Only by both privileged and - * unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_FLASH_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __unprivileged_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __unprivileged_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup unprivileged syscalls flash as Read Only by both privileged + * and unprivileged tasks. All tasks can read it but no-one can modify. */ + portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_READ_ONLY ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup unprivileged syscalls flash as Read Only by both privileged - * and unprivileged tasks. All tasks can read it but no-one can modify. */ - portMPU_RNR_REG = portUNPRIVILEGED_SYSCALLS_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __syscalls_flash_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_READ_ONLY ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __syscalls_flash_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Setup RAM containing kernel data for privileged access only. */ + portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; + portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | + ( portMPU_REGION_NON_SHAREABLE ) | + ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | + ( portMPU_REGION_EXECUTE_NEVER ); + portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | + ( portMPU_RLAR_ATTR_INDEX0 ) | + ( portMPU_RLAR_REGION_ENABLE ); - /* Setup RAM containing kernel data for privileged access only. */ - portMPU_RNR_REG = portPRIVILEGED_RAM_REGION; - portMPU_RBAR_REG = ( ( ( uint32_t ) __privileged_sram_start__ ) & portMPU_RBAR_ADDRESS_MASK ) | - ( portMPU_REGION_NON_SHAREABLE ) | - ( portMPU_REGION_PRIVILEGED_READ_WRITE ) | - ( portMPU_REGION_EXECUTE_NEVER ); - portMPU_RLAR_REG = ( ( ( uint32_t ) __privileged_sram_end__ ) & portMPU_RLAR_ADDRESS_MASK ) | - ( portMPU_RLAR_ATTR_INDEX0 ) | - ( portMPU_RLAR_REGION_ENABLE ); + /* Enable mem fault. */ + portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - /* Enable mem fault. */ - portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_MEM_FAULT_ENABLE_BIT; - - /* Enable MPU with privileged background access i.e. unmapped - * regions have privileged access. */ - portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); - } + /* Enable MPU with privileged background access i.e. unmapped + * regions have privileged access. */ + portMPU_CTRL_REG |= ( portMPU_PRIV_BACKGROUND_ENABLE_BIT | portMPU_ENABLE_BIT ); } #endif /* configENABLE_MPU */ @@ -1108,47 +1098,47 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO switch( ucSVCNumber ) { - #if ( configENABLE_TRUSTZONE == 1 ) - case portSVC_ALLOCATE_SECURE_CONTEXT: + #if ( configENABLE_TRUSTZONE == 1 ) + case portSVC_ALLOCATE_SECURE_CONTEXT: - /* R0 contains the stack size passed as parameter to the - * vPortAllocateSecureContext function. */ - ulR0 = pulCallerStackAddress[ 0 ]; + /* R0 contains the stack size passed as parameter to the + * vPortAllocateSecureContext function. */ + ulR0 = pulCallerStackAddress[ 0 ]; - #if ( configENABLE_MPU == 1 ) - { - /* Read the CONTROL register value. */ - __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); + #if ( configENABLE_MPU == 1 ) + { + /* Read the CONTROL register value. */ + __asm volatile ( "mrs %0, control" : "=r" ( ulControl ) ); - /* The task that raised the SVC is privileged if Bit[0] - * in the CONTROL register is 0. */ - ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); + /* The task that raised the SVC is privileged if Bit[0] + * in the CONTROL register is 0. */ + ulIsTaskPrivileged = ( ( ulControl & portCONTROL_PRIVILEGED_MASK ) == 0 ); - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); - } - #else /* if ( configENABLE_MPU == 1 ) */ - { - /* Allocate and load a context for the secure task. */ - xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); - } - #endif /* configENABLE_MPU */ + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, ulIsTaskPrivileged, pxCurrentTCB ); + } + #else /* if ( configENABLE_MPU == 1 ) */ + { + /* Allocate and load a context for the secure task. */ + xSecureContext = SecureContext_AllocateContext( ulR0, pxCurrentTCB ); + } + #endif /* configENABLE_MPU */ - configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); - SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); - break; + configASSERT( xSecureContext != securecontextINVALID_CONTEXT_ID ); + SecureContext_LoadContext( xSecureContext, pxCurrentTCB ); + break; - case portSVC_FREE_SECURE_CONTEXT: + case portSVC_FREE_SECURE_CONTEXT: - /* R0 contains TCB being freed and R1 contains the secure - * context handle to be freed. */ - ulR0 = pulCallerStackAddress[ 0 ]; - ulR1 = pulCallerStackAddress[ 1 ]; + /* R0 contains TCB being freed and R1 contains the secure + * context handle to be freed. */ + ulR0 = pulCallerStackAddress[ 0 ]; + ulR1 = pulCallerStackAddress[ 1 ]; - /* Free the secure context. */ - SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); - break; - #endif /* configENABLE_TRUSTZONE */ + /* Free the secure context. */ + SecureContext_FreeContext( ( SecureContextHandle_t ) ulR1, ( void * ) ulR0 ); + break; + #endif /* configENABLE_TRUSTZONE */ case portSVC_START_SCHEDULER: #if ( configENABLE_TRUSTZONE == 1 ) @@ -1174,24 +1164,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO vRestoreContextOfFirstTask(); break; - #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) - case portSVC_RAISE_PRIVILEGE: + #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) ) + case portSVC_RAISE_PRIVILEGE: - /* Only raise the privilege, if the svc was raised from any of - * the system calls. */ - if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && - ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) - { - vRaisePrivilege(); - } - break; - #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ + /* Only raise the privilege, if the svc was raised from any of + * the system calls. */ + if( ( ulPC >= ( uint32_t ) __syscalls_flash_start__ ) && + ( ulPC <= ( uint32_t ) __syscalls_flash_end__ ) ) + { + vRaisePrivilege(); + } + break; + #endif /* ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 1 ) */ - #if ( configENABLE_MPU == 1 ) - case portSVC_YIELD: - vPortYield(); - break; - #endif /* configENABLE_MPU == 1 */ + #if ( configENABLE_MPU == 1 ) + case portSVC_YIELD: + vPortYield(); + break; + #endif /* configENABLE_MPU == 1 */ default: /* Incorrect SVC call. */ @@ -1210,7 +1200,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1246,12 +1236,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1261,20 +1255,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -1310,7 +1304,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Record if the hardware used padding to force the stack pointer * to be double word aligned. */ @@ -1360,7 +1354,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i; #if defined( __ARMCC_VERSION ) @@ -1392,12 +1386,16 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ #if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) { if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; __asm volatile ( " vpush {s0} \n" /* Trigger lazy stacking. */ " vpop {s0} \n" /* Nullify the affect of the above instruction. */ @@ -1407,20 +1405,20 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } } #else /* if ( ( configENABLE_FPU == 1 ) || ( configENABLE_MVE == 1 ) ) */ { - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } #endif /* configENABLE_FPU || configENABLE_MVE */ /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } @@ -1518,21 +1516,21 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO xMPUSettings->ulContext[ ulIndex ] = 0x11111111; /* r11. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pvParameters; /* r0. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ + xMPUSettings->ulContext[ ulIndex ] = 0x01010101; /* r1. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ + xMPUSettings->ulContext[ ulIndex ] = 0x02020202; /* r2. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ + xMPUSettings->ulContext[ ulIndex ] = 0x03030303; /* r3. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ + xMPUSettings->ulContext[ ulIndex ] = 0x12121212; /* r12. */ ulIndex++; xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portTASK_RETURN_ADDRESS; /* LR. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxCode; /* PC. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ + xMPUSettings->ulContext[ ulIndex ] = portINITIAL_XPSR; /* xPSR. */ ulIndex++; #if ( configENABLE_TRUSTZONE == 1 ) @@ -1543,7 +1541,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO #endif /* configENABLE_TRUSTZONE */ xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) ( pxTopOfStack - 8 ); /* PSP with the hardware saved stack. */ ulIndex++; - xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ + xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */ ulIndex++; #if ( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) ) @@ -1615,15 +1613,15 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO * interrupt. */ #if ( portPRELOAD_REGISTERS == 0 ) { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ - pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ - pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ + pxTopOfStack -= 5; /* R12, R3, R2 and R1. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + pxTopOfStack -= 9; /* R11..R4, EXC_RETURN. */ *pxTopOfStack = portINITIAL_EXC_RETURN; pxTopOfStack--; *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ @@ -1637,42 +1635,42 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO } #else /* portPRELOAD_REGISTERS */ { - pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ - *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ + pxTopOfStack--; /* Offset added to account for the way the MCU uses the stack on entry/exit of interrupts. */ + *pxTopOfStack = portINITIAL_XPSR; /* xPSR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ + *pxTopOfStack = ( StackType_t ) pxCode; /* PC. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) portTASK_RETURN_ADDRESS; /* LR. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ + *pxTopOfStack = ( StackType_t ) 0x12121212UL; /* R12. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ + *pxTopOfStack = ( StackType_t ) 0x03030303UL; /* R3. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ + *pxTopOfStack = ( StackType_t ) 0x02020202UL; /* R2. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ + *pxTopOfStack = ( StackType_t ) 0x01010101UL; /* R1. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ + *pxTopOfStack = ( StackType_t ) pvParameters; /* R0. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ + *pxTopOfStack = ( StackType_t ) 0x11111111UL; /* R11. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ + *pxTopOfStack = ( StackType_t ) 0x10101010UL; /* R10. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ + *pxTopOfStack = ( StackType_t ) 0x09090909UL; /* R09. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ + *pxTopOfStack = ( StackType_t ) 0x08080808UL; /* R08. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ + *pxTopOfStack = ( StackType_t ) 0x07070707UL; /* R07. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ + *pxTopOfStack = ( StackType_t ) 0x06060606UL; /* R06. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ + *pxTopOfStack = ( StackType_t ) 0x05050505UL; /* R05. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ + *pxTopOfStack = ( StackType_t ) 0x04040404UL; /* R04. */ pxTopOfStack--; - *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ + *pxTopOfStack = portINITIAL_EXC_RETURN; /* EXC_RETURN. */ pxTopOfStack--; - *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ + *pxTopOfStack = ( StackType_t ) pxEndOfStack; /* Slot used to hold this task's PSPLIM value. */ #if ( configENABLE_TRUSTZONE == 1 ) { diff --git a/portable/IAR/RISC-V/port.c b/portable/IAR/RISC-V/port.c index 8040022bd..820423ec5 100644 --- a/portable/IAR/RISC-V/port.c +++ b/portable/IAR/RISC-V/port.c @@ -98,7 +98,7 @@ void vPortSetupTimerInterrupt( void ) __attribute__( ( weak ) ); uint64_t ullNextTime = 0ULL; const uint64_t * pullNextTime = &ullNextTime; const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */ -uint64_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; +UBaseType_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS; volatile uint64_t * pullMachineTimerCompareRegister = NULL; /* Holds the critical nesting value - deliberately non-zero at start up to diff --git a/portable/IAR/RL78/portmacro.h b/portable/IAR/RL78/portmacro.h index 544e76e9e..36697a620 100644 --- a/portable/IAR/RL78/portmacro.h +++ b/portable/IAR/RL78/portmacro.h @@ -187,7 +187,7 @@ * ; * memory mode) registers the _usCriticalNesting value and the Stack Pointer * ; * of the active Task onto the task stack. * ; *---------------------------------------------------------------------------*/ - portSAVE_CONTEXT MACRO +portSAVE_CONTEXT MACRO PUSH AX; /* Save AX Register to stack. */ PUSH HL #if __CODE_MODEL__ == __CODE_MODEL_FAR__ @@ -217,7 +217,7 @@ * ; * general purpose registers and the CS and ES (only in __far memory mode) * ; * of the selected task from the task stack. * ; *---------------------------------------------------------------------------*/ - portRESTORE_CONTEXT MACRO +portRESTORE_CONTEXT MACRO MOVW AX, _pxCurrentTCB; /* Restore the Task stack pointer. */ MOVW HL, AX MOVW AX, [ HL ] diff --git a/portable/MPLAB/PIC32MZ/port.c b/portable/MPLAB/PIC32MZ/port.c index 034fc26d1..4af1fb832 100644 --- a/portable/MPLAB/PIC32MZ/port.c +++ b/portable/MPLAB/PIC32MZ/port.c @@ -234,6 +234,11 @@ __attribute__(( weak )) void vApplicationSetupTickTimerInterrupt( void ) { const uint32_t ulCompareMatch = ( (configPERIPHERAL_CLOCK_HZ / portTIMER_PRESCALE) / configTICK_RATE_HZ ) - 1UL; + /* PR1 is 16-bit. Ensure that the configPERIPHERAL_CLOCK_HZ and + * configTICK_RATE_HZ are defined such that ulCompareMatch value would fit + * in 16-bits. */ + configASSERT( ( ulCompareMatch & 0xFFFF0000 ) == 0 ); + T1CON = 0x0000; T1CONbits.TCKPS = portPRESCALE_BITS; PR1 = ulCompareMatch; diff --git a/portable/MSVC-MingW/port.c b/portable/MSVC-MingW/port.c index 9ce0c1b15..540c4a4bc 100644 --- a/portable/MSVC-MingW/port.c +++ b/portable/MSVC-MingW/port.c @@ -33,6 +33,14 @@ #include "FreeRTOS.h" #include "task.h" +#ifdef WIN32_LEAN_AND_MEAN + #include +#else + #include +#endif + +#include + #ifdef __GNUC__ #include "mmsystem.h" #else @@ -144,6 +152,7 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) TickType_t xWaitTimeBetweenTicks = portTICK_PERIOD_MS; HANDLE hTimer = NULL; LARGE_INTEGER liDueTime; + BOOL bSuccess; /* Set the timer resolution to the maximum possible. */ if( timeGetDevCaps( &xTimeCaps, sizeof( xTimeCaps ) ) == MMSYSERR_NOERROR ) @@ -182,7 +191,8 @@ static DWORD WINAPI prvSimulatedPeripheralTimer( LPVOID lpParameter ) /* Set the Waitable Timer. The timer is set to run periodically at every xWaitTimeBetweenTicks milliseconds. */ - configASSERT( SetWaitableTimer( hTimer, &liDueTime, xWaitTimeBetweenTicks, NULL, NULL, 0 ) ); + bSuccess = SetWaitableTimer( hTimer, &liDueTime, xWaitTimeBetweenTicks, NULL, NULL, 0 ); + configASSERT( bSuccess ); while( xPortRunning == pdTRUE ) { diff --git a/portable/MSVC-MingW/portmacro.h b/portable/MSVC-MingW/portmacro.h index eb94758be..37bfb2586 100644 --- a/portable/MSVC-MingW/portmacro.h +++ b/portable/MSVC-MingW/portmacro.h @@ -29,17 +29,6 @@ #ifndef PORTMACRO_H #define PORTMACRO_H -#ifdef WIN32_LEAN_AND_MEAN - #include -#else - #include -#endif - -#include -#include -#include -#include - #ifdef __cplusplus extern "C" { #endif @@ -156,22 +145,25 @@ void vPortExitCritical( void ); : "cc" ) #else /* __GNUC__ */ + #include /* BitScanReverse returns the bit position of the most significant '1' * in the word. */ #if defined( __x86_64__ ) || defined( _M_X64 ) + #pragma intrinsic(_BitScanReverse64) #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ do \ { \ - DWORD ulTopPriority; \ + unsigned long ulTopPriority; \ _BitScanReverse64( &ulTopPriority, ( uxReadyPriorities ) ); \ uxTopPriority = ulTopPriority; \ } while( 0 ) #else /* #if defined( __x86_64__ ) || defined( _M_X64 ) */ + #pragma intrinsic(_BitScanReverse) - #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( DWORD * ) &( uxTopPriority ), ( uxReadyPriorities ) ) + #define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) _BitScanReverse( ( unsigned long * ) &( uxTopPriority ), ( uxReadyPriorities ) ) #endif /* #if defined( __x86_64__ ) || defined( _M_X64 ) */ diff --git a/portable/MemMang/heap_4.c b/portable/MemMang/heap_4.c index acb334757..50af15dfb 100644 --- a/portable/MemMang/heap_4.c +++ b/portable/MemMang/heap_4.c @@ -572,7 +572,7 @@ static void prvInsertBlockIntoFreeList( BlockLink_t * pxBlockToInsert ) /* PRIVI void vPortGetHeapStats( HeapStats_t * pxHeapStats ) { BlockLink_t * pxBlock; - size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ + size_t xBlocks = 0, xMaxSize = 0, xMinSize = SIZE_MAX; vTaskSuspendAll(); { diff --git a/portable/MemMang/heap_5.c b/portable/MemMang/heap_5.c index 4e872f615..bf321304f 100644 --- a/portable/MemMang/heap_5.c +++ b/portable/MemMang/heap_5.c @@ -672,7 +672,7 @@ void vPortDefineHeapRegions( const HeapRegion_t * const pxHeapRegions ) /* PRIVI void vPortGetHeapStats( HeapStats_t * pxHeapStats ) { BlockLink_t * pxBlock; - size_t xBlocks = 0, xMaxSize = 0, xMinSize = portMAX_DELAY; /* portMAX_DELAY used as a portable way of getting the maximum value. */ + size_t xBlocks = 0, xMaxSize = 0, xMinSize = SIZE_MAX; vTaskSuspendAll(); { diff --git a/portable/RVDS/ARM_CM4_MPU/port.c b/portable/RVDS/ARM_CM4_MPU/port.c index 307ae6d02..450b86211 100644 --- a/portable/RVDS/ARM_CM4_MPU/port.c +++ b/portable/RVDS/ARM_CM4_MPU/port.c @@ -1,6 +1,8 @@ /* * FreeRTOS Kernel * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright 2025 Arm Limited and/or its affiliates + * * * SPDX-License-Identifier: MIT * @@ -474,7 +476,7 @@ void vSVCHandler_C( uint32_t * pulParam ) extern UBaseType_t uxSystemCallImplementations[ NUM_SYSTEM_CALLS ]; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulSystemCallStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i, r1; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i, r1; extern uint32_t __syscalls_flash_start__; extern uint32_t __syscalls_flash_end__; @@ -500,23 +502,27 @@ void vSVCHandler_C( uint32_t * pulParam ) { pulSystemCallStack = pxMpuSettings->xSystemCallStackInfo.pulSystemCallStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; prvTriggerLazyStacking(); } else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the system call stack for the stack frame. */ - pulSystemCallStack = pulSystemCallStack - ulStackFrameSize; + pulSystemCallStack = pulSystemCallStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulSystemCallStack[ i ] = pulTaskStack[ i ]; } @@ -537,7 +543,7 @@ void vSVCHandler_C( uint32_t * pulParam ) /* Remember the location where we should copy the stack frame when we exit from * the system call. */ - pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulStackFrameSize; + pxMpuSettings->xSystemCallStackInfo.pulTaskStack = pulTaskStack + ulHardwareSavedExceptionFrameSize; /* Store the value of the Link Register before the SVC was raised. * It contains the address of the caller of the System Call entry @@ -592,7 +598,7 @@ void vSVCHandler_C( uint32_t * pulParam ) extern TaskHandle_t pxCurrentTCB; xMPU_SETTINGS * pxMpuSettings; uint32_t * pulTaskStack; - uint32_t ulStackFrameSize, ulSystemCallLocation, i, r1; + uint32_t ulHardwareSavedExceptionFrameSize, ulSystemCallLocation, i, r1; extern uint32_t __privileged_functions_start__; extern uint32_t __privileged_functions_end__; @@ -614,23 +620,27 @@ void vSVCHandler_C( uint32_t * pulParam ) { pulTaskStack = pxMpuSettings->xSystemCallStackInfo.pulTaskStack; + /* Hardware Saved Stack Frame Size upon Exception entry: + * - No FPU: basic frame (R0-R3, R12, LR, PC, and xPSR) = 8 words. + * - With FPU (lazy stacking): basic frame + S0–S15 + FPSCR + reserved word = 26 words. + */ if( ( ulLR & portEXC_RETURN_STACK_FRAME_TYPE_MASK ) == 0UL ) { /* Extended frame i.e. FPU in use. */ - ulStackFrameSize = 26; + ulHardwareSavedExceptionFrameSize = 26; prvTriggerLazyStacking(); } else { /* Standard frame i.e. FPU not in use. */ - ulStackFrameSize = 8; + ulHardwareSavedExceptionFrameSize = 8; } /* Make space on the task stack for the stack frame. */ - pulTaskStack = pulTaskStack - ulStackFrameSize; + pulTaskStack = pulTaskStack - ulHardwareSavedExceptionFrameSize; /* Copy the stack frame. */ - for( i = 0; i < ulStackFrameSize; i++ ) + for( i = 0; i < ulHardwareSavedExceptionFrameSize; i++ ) { pulTaskStack[ i ] = pulSystemCallStack[ i ]; } diff --git a/portable/ThirdParty/GCC/ARM_TFM/README.md b/portable/ThirdParty/GCC/ARM_TFM/README.md index 7df149f54..bc594b156 100644 --- a/portable/ThirdParty/GCC/ARM_TFM/README.md +++ b/portable/ThirdParty/GCC/ARM_TFM/README.md @@ -52,13 +52,13 @@ Kernel runs in the Non-Secure Side. The setting of this macro is decided by the setting in Secure Side which is platform-specific. If the Secure Side enables Non-Secure access to FPU, then this macro can be configured as 0 or 1. Otherwise, this macro can only be configured as 0. Please note that Cortex-M23 does not support FPU. -Please refer to [TF-M documentation](https://tf-m-user-guide.trustedfirmware.org/integration_guide/tfm_fpu_support.html) for FPU usage on the Non-Secure side. +Please refer to [TF-M documentation](https://trustedfirmware-m.readthedocs.io/en/latest/integration_guide/tfm_fpu_support.html) for FPU usage on the Non-Secure side. * `configENABLE_MVE` The setting of this macro is decided by the setting in Secure Side which is platform-specific. If the Secure Side enables Non-Secure access to MVE, then this macro can be configured as 0 or 1. Otherwise, this macro can only be configured as 0. Please note that only Cortex-M55 and Cortex-M85 support MVE. -Please refer to [TF-M documentation](https://tf-m-user-guide.trustedfirmware.org/integration_guide/tfm_fpu_support.html) for MVE usage on the Non-Secure side. +Please refer to [TF-M documentation](https://trustedfirmware-m.readthedocs.io/en/latest/integration_guide/tfm_fpu_support.html) for MVE usage on the Non-Secure side. * `configENABLE_TRUSTZONE` This macro should be configured as 0 because TF-M doesn't use the secure context management function of FreeRTOS. New secure context management might be introduced when TF-M supports multiple secure context. diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index dd7ca1a9a..a1b1ca8c7 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -48,8 +48,8 @@ * stdio (printf() and friends) should be called from a single task * only or serialized with a FreeRTOS primitive such as a binary * semaphore or mutex. -* -* Note: When using LLDB (the default debugger on macOS) with this port, +* +* Note: When using LLDB (the default debugger on macOS) with this port, * suppress SIGUSR1 to prevent debugger interference. This can be * done by adding the following line to ~/.lldbinit: * `process handle SIGUSR1 -n true -p false -s false` @@ -140,6 +140,8 @@ static void prvThreadKeyDestructor( void * pvData ) static void prvInitThreadKey( void ) { pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); + /* Destroy xThreadKey when the process exits. */ + atexit( prvDestroyThreadKey ); } /*-----------------------------------------------------------*/ @@ -193,7 +195,7 @@ void prvFatalError( const char * pcCall, } /*-----------------------------------------------------------*/ -static void prvPortSetCurrentThreadName( char * pxThreadName ) +static void prvPortSetCurrentThreadName( const char * pxThreadName ) { #ifdef __APPLE__ pthread_setname_np( pxThreadName ); @@ -227,6 +229,7 @@ StackType_t * pxPortInitialiseStack( StackType_t * pxTopOfStack, /* Ensure that there is enough space to store Thread_t on the stack. */ ulStackSize = ( size_t ) ( pxTopOfStack + 1 - pxEndOfStack ) * sizeof( *pxTopOfStack ); configASSERT( ulStackSize > sizeof( Thread_t ) ); + ( void ) ulStackSize; /* suppress set but not used warning */ thread->pxCode = pxCode; thread->pvParams = pvParameters; @@ -315,8 +318,6 @@ BaseType_t xPortStartScheduler( void ) /* Restore original signal mask. */ ( void ) pthread_sigmask( SIG_SETMASK, &xSchedulerOriginalSignalMask, NULL ); - prvDestroyThreadKey(); - return 0; } /*-----------------------------------------------------------*/ @@ -324,17 +325,23 @@ BaseType_t xPortStartScheduler( void ) void vPortEndScheduler( void ) { Thread_t * pxCurrentThread; + BaseType_t xIsFreeRTOSThread; /* Stop the timer tick thread. */ xTimerTickThreadShouldRun = false; pthread_join( hTimerTickThread, NULL ); + /* Check whether the current thread is a FreeRTOS thread. + * This has to happen before the scheduler is signaled to exit + * its loop to prevent data races on the thread key. */ + xIsFreeRTOSThread = prvIsFreeRTOSThread(); + /* Signal the scheduler to exit its loop. */ xSchedulerEnd = pdTRUE; ( void ) pthread_kill( hMainThread, SIG_RESUME ); /* Waiting to be deleted here. */ - if( prvIsFreeRTOSThread() == pdTRUE ) + if( xIsFreeRTOSThread == pdTRUE ) { pxCurrentThread = prvGetThreadFromTask( xTaskGetCurrentTaskHandle() ); event_wait( pxCurrentThread->ev ); diff --git a/portable/ThirdParty/GCC/RP2040/include/portmacro.h b/portable/ThirdParty/GCC/RP2040/include/portmacro.h index 802470e33..3e54f384f 100644 --- a/portable/ThirdParty/GCC/RP2040/include/portmacro.h +++ b/portable/ThirdParty/GCC/RP2040/include/portmacro.h @@ -227,7 +227,7 @@ static inline void vPortRecursiveLock( BaseType_t xCoreID, if( ucOwnedByCore[ xCoreID ][ ulLockNum ] ) { configASSERT( ucRecursionCountByLock[ ulLockNum ] != 255u ); - ucRecursionCountByLock[ ulLockNum ]++; + ucRecursionCountByLock[ ulLockNum ] = ucRecursionCountByLock[ ulLockNum ] + 1; return; } spin_lock_unsafe_blocking(pxSpinLock); @@ -241,7 +241,8 @@ static inline void vPortRecursiveLock( BaseType_t xCoreID, configASSERT( ( ucOwnedByCore[ xCoreID ] [ulLockNum ] ) != 0 ); configASSERT( ucRecursionCountByLock[ ulLockNum ] != 0 ); - if( !--ucRecursionCountByLock[ ulLockNum ] ) + ucRecursionCountByLock[ ulLockNum ] = ucRecursionCountByLock[ ulLockNum ] - 1; + if ( ucRecursionCountByLock[ ulLockNum ] == 0U ) { ucOwnedByCore[ xCoreID ] [ ulLockNum ] = 0; spin_unlock_unsafe(pxSpinLock); diff --git a/queue.c b/queue.c index e91d9e39b..a967839de 100644 --- a/queue.c +++ b/queue.c @@ -833,6 +833,10 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, if( pxMutex->u.xSemaphore.xMutexHolder == xTaskGetCurrentTaskHandle() ) { ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + + /* Check if an overflow occurred. */ + configASSERT( pxMutex->u.xSemaphore.uxRecursiveCallCount ); + xReturn = pdPASS; } else @@ -845,6 +849,9 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, if( xReturn != pdFAIL ) { ( pxMutex->u.xSemaphore.uxRecursiveCallCount )++; + + /* Check if an overflow occurred. */ + configASSERT( pxMutex->u.xSemaphore.uxRecursiveCallCount ); } else { @@ -1168,9 +1175,8 @@ BaseType_t xQueueGenericSendFromISR( QueueHandle_t xQueue, traceENTER_xQueueGenericSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken, xCopyPosition ); - configASSERT( pxQueue ); - configASSERT( !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); - configASSERT( !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); + configASSERT( ( pxQueue != NULL ) && !( ( pvItemToQueue == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( ( pxQueue != NULL ) && !( ( xCopyPosition == queueOVERWRITE ) && ( pxQueue->uxLength != 1 ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are @@ -1344,16 +1350,14 @@ BaseType_t xQueueGiveFromISR( QueueHandle_t xQueue, * not (i.e. has a task with a higher priority than us been woken by this * post). */ - configASSERT( pxQueue ); - /* xQueueGenericSendFromISR() should be used instead of xQueueGiveFromISR() * if the item size is not 0. */ - configASSERT( pxQueue->uxItemSize == 0 ); + configASSERT( ( pxQueue != NULL ) && ( pxQueue->uxItemSize == 0 ) ); /* Normally a mutex would not be given from an interrupt, especially if * there is a mutex holder, as priority inheritance makes no sense for an - * interrupts, only tasks. */ - configASSERT( !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); + * interrupt, only tasks. */ + configASSERT( ( pxQueue != NULL ) && !( ( pxQueue->uxQueueType == queueQUEUE_IS_MUTEX ) && ( pxQueue->u.xSemaphore.xMutexHolder != NULL ) ) ); /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are @@ -1888,12 +1892,9 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, traceENTER_xQueuePeek( xQueue, pvBuffer, xTicksToWait ); - /* Check the pointer is not NULL. */ - configASSERT( ( pxQueue ) ); - /* The buffer into which data is received can only be NULL if the data size * is zero (so no data is copied into the buffer. */ - configASSERT( !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( ( pxQueue != NULL ) && !( ( ( pvBuffer ) == NULL ) && ( ( pxQueue )->uxItemSize != ( UBaseType_t ) 0U ) ) ); /* Cannot block if the scheduler is suspended. */ #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) ) @@ -2145,9 +2146,8 @@ BaseType_t xQueuePeekFromISR( QueueHandle_t xQueue, traceENTER_xQueuePeekFromISR( xQueue, pvBuffer ); - configASSERT( pxQueue ); - configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); - configASSERT( pxQueue->uxItemSize != 0 ); /* Can't peek a semaphore. */ + configASSERT( ( pxQueue != NULL ) && !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); + configASSERT( ( pxQueue != NULL ) && ( pxQueue->uxItemSize != 0 ) ); /* Can't peek a semaphore. */ /* RTOS ports that support interrupt nesting have the concept of a maximum * system call (or maximum API call) interrupt priority. Interrupts that are diff --git a/stream_buffer.c b/stream_buffer.c index b1f9c0d57..4f13c679b 100644 --- a/stream_buffer.c +++ b/stream_buffer.c @@ -1653,11 +1653,9 @@ void vStreamBufferSetStreamBufferNotificationIndex( StreamBufferHandle_t xStream traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex ); - configASSERT( pxStreamBuffer ); - /* There should be no task waiting otherwise we'd never resume them. */ - configASSERT( pxStreamBuffer->xTaskWaitingToReceive == NULL ); - configASSERT( pxStreamBuffer->xTaskWaitingToSend == NULL ); + configASSERT( ( pxStreamBuffer != NULL ) && ( pxStreamBuffer->xTaskWaitingToReceive == NULL ) ); + configASSERT( ( pxStreamBuffer != NULL ) && ( pxStreamBuffer->xTaskWaitingToSend == NULL ) ); /* Check that the task notification index is valid. */ configASSERT( uxNotificationIndex < configTASK_NOTIFICATION_ARRAY_ENTRIES ); diff --git a/tasks.c b/tasks.c index 24cfb2620..1e6ecdc9e 100644 --- a/tasks.c +++ b/tasks.c @@ -893,7 +893,7 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB ) PRIVILEGED_FUNCTION; BaseType_t xCurrentCoreTaskPriority; BaseType_t xLowestPriorityCore = ( BaseType_t ) -1; BaseType_t xCoreID; - const BaseType_t xCurrentCoreID = portGET_CORE_ID(); + const BaseType_t xCurrentCoreID = ( BaseType_t ) portGET_CORE_ID(); #if ( configRUN_MULTIPLE_PRIORITIES == 0 ) BaseType_t xYieldCount = 0;